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

Android中使用RSA解密AES密钥的问题排查与实现指引

问题根源与解决方案

我来帮你排查并解决这个问题,咱们一步步拆解:

1. 核心错误:RSA密钥对不匹配

你在生成密钥对的时候犯了一个致命错误——连续调用了两次keyGen.genKeyPair(),一次提取公钥,一次提取私钥。这会生成两组完全独立的RSA密钥对,用这个公钥加密的数据,用那个无关的私钥自然解不开,直接触发BadPaddingException。

修正后的密钥生成代码

KeyPairGenerator keyGen = null;
try {
    keyGen = KeyPairGenerator.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
    e.printStackTrace();
}
keyGen.initialize(1024);
// 只生成一次密钥对!公钥私钥必须来自同一对
KeyPair keyPair = keyGen.genKeyPair();
byte[] publicKey = keyPair.getPublic().getEncoded();
byte[] privateKey = keyPair.getPrivate().getEncoded();
Util.save("privateKey", rsa.encryptBASE64(privateKey), this);
Util.save("publicKey", rsa.encryptBASE64(publicKey), this);

2. Base64工具类参数错误

你的Base64编码/解码方法里重复设置了NO_PADDING,而且URL_SAFE与NO_PADDING组合可能导致数据长度不匹配(Base64通常需要填充到4的倍数才能正确解码)。建议调整参数,保持编码解码的一致性:

public static byte[] decryptBASE64(String key) {
    // 去掉重复的NO_PADDING,保持参数统一
    return Base64.decode(key, Base64.NO_WRAP | Base64.URL_SAFE);
}
public static String encryptBASE64(byte[] key) {
    return Base64.encodeToString(key, Base64.NO_WRAP | Base64.URL_SAFE);
}

如果不需要URL安全的字符替换,直接用Base64.DEFAULT也可以,能避免不必要的兼容性问题。

3. 解密后AES密钥的转换

当你用RSA解密出AES密钥的字节数组后,直接用SecretKeySpec生成可用的AES密钥即可——因为你加密的本来就是secretKey.getEncoded()(AES密钥的原始字节):

// 解密得到AES密钥的原始字节数组
byte[] aesKeyRecovered = rsa.decryptByPrivateKey(rsa.decryptBASE64(aesKeyCipherBase64),myPrivateKeyString);
// 转换为可直接使用的AES密钥
SecretKey recoveredAesKey = new SecretKeySpec(aesKeyRecovered, "AES");

这样就可以用这个密钥解密之前AES加密的文件了。

测试逻辑验证

你的加密解密连续测试逻辑是对的,修正密钥对后可以加上断言验证一致性:

// 假设secretKey是你的原始16字节AES密钥
String aesKeyCipherBase64 = rsa.encryptBASE64(rsa.encryptByPublicKey(secretKey.getEncoded(), myPublicKeyString));
byte[] aesKeyRecovered = rsa.decryptByPrivateKey(rsa.decryptBASE64(aesKeyCipherBase64),myPrivateKeyString);
// 验证解密后的密钥与原始密钥是否一致
assert Arrays.equals(secretKey.getEncoded(), aesKeyRecovered);

额外建议

  • RSA 1024位目前已被认为安全性不足,建议至少升级到2048位密钥。
  • 确保加密和解密时的Cipher算法字符串完全一致(你用的RSA/ECB/PKCS1Padding是标准且正确的)。
  • 异常处理不要只打印堆栈,最好添加业务层面的错误提示,避免程序无响应崩溃。

内容的提问来源于stack exchange,提问作者Sijo Josan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 15:27:32