You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用RSA私钥加密字符串时遭遇InvalidKeySpecException求助

问题解决:InvalidKeySpecException 私钥加密报错

问题描述

我有一个如下格式的私钥文件:

-----BEGIN PRIVATE KEY-----
[content]
-----END PRIVATE KEY-----

我希望使用该私钥加密字符串数据,编写了如下代码:

fun encryptData(txt: String, pk: String): String {
    var encoded = ""
    var encrypted: ByteArray? = null
    try {
        val publicBytes: ByteArray = Base64.decode(pk, Base64.DEFAULT)
        val keySpec = X509EncodedKeySpec(publicBytes)
        val keyFactory: KeyFactory = KeyFactory.getInstance("RSA")
        val pubKey: PrivateKey = keyFactory.generatePrivate(keySpec)
        val cipher: Cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING")
        cipher.init(Cipher.ENCRYPT_MODE, pubKey)
        encrypted = cipher.doFinal(txt.toByteArray())
        encoded = Base64.encodeToString(encrypted, Base64.DEFAULT)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return encoded
}

但每次尝试编码时都会抛出InvalidKeySpecException,求解决方法。

错误原因及修复方案

1. 私钥格式处理错误

传入的私钥包含-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----的头部尾部,直接Base64解码会解析失败,必须先去除这些无关行,只保留中间的Base64内容。

2. 密钥规范类用错

X509EncodedKeySpec是用于公钥的编码规范,私钥应该使用PKCS8EncodedKeySpec(你的私钥是PKCS#8格式,对应这个类)。

3. 变量命名与逻辑修正

代码里变量名pubKey实际指向私钥,建议修正命名避免混淆;同时确保KeyFactory生成私钥的逻辑匹配私钥规范。

修复后的代码

fun encryptData(txt: String, pk: String): String {
    var encoded = ""
    var encrypted: ByteArray? = null
    try {
        // 去除私钥的头部尾部及空白字符
        val cleanPk = pk.replace("-----BEGIN PRIVATE KEY-----", "")
                         .replace("-----END PRIVATE KEY-----", "")
                         .replace("\\s+".toRegex(), "")
        // Base64解码处理后的私钥字符串
        val privateBytes: ByteArray = Base64.decode(cleanPk, Base64.DEFAULT)
        // 使用私钥对应的PKCS8规范
        val keySpec = PKCS8EncodedKeySpec(privateBytes)
        val keyFactory: KeyFactory = KeyFactory.getInstance("RSA")
        // 生成私钥实例
        val privateKey: PrivateKey = keyFactory.generatePrivate(keySpec)
        val cipher: Cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING")
        cipher.init(Cipher.ENCRYPT_MODE, privateKey)
        encrypted = cipher.doFinal(txt.toByteArray())
        encoded = Base64.encodeToString(encrypted, Base64.DEFAULT)
    } catch (e: Exception) {
        e.printStackTrace()
    }
    return encoded
}

额外说明

常规RSA场景中,标准流程是公钥加密、私钥解密;如果你的需求是为数据做签名(验证数据来源可信),除了用私钥加密的方式,更规范的做法是使用Signature类实现,更符合安全标准。

内容的提问来源于stack exchange,提问作者Toufiq Akbar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 08:45:29