RSA解密突发故障排查:原正常代码抛出BadBlockException
服务器上RSA解密代码突然报错故障排查
此前在服务器上运行正常的RSA解密代码,近期突然抛出异常并终止运行,相关代码及异常信息如下:
解密代码
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); rsa = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC"); String key = getKeyString(); Reader privateKeyReader = new StringReader(key); PEMParser privatePemParser = new PEMParser(privateKeyReader); Object privateObject = privatePemParser.readObject(); PrivateKey privateKey; if (privateObject instanceof PEMKeyPair pemKeyPair) { JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC"); privateKey = converter.getPrivateKey(pemKeyPair.getPrivateKeyInfo()); } else { throw new KeyException("rsa key error"); } rsa.init(Cipher.DECRYPT_MODE, privateKey); byte[] decodeKey = Base64.getDecoder().decode(encryptRandomKey); byte[] utf8 = Decipherer.rsa.doFinal(decodeKey); return new String(utf8, StandardCharsets.UTF_8);
抛出异常
org.bouncycastle.jcajce.provider.util.BadBlockException: unable to decrypt block at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.getOutput(Unknown Source) ~[bcprov-jdk15on-1.64.jar:1.64.0] at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source) ~[bcprov-jdk15on-1.64.jar:1.64.0] at javax.crypto.Cipher.doFinal(Cipher.java:2205) ~[?:?] at com.pjcy.pullwechatmsg.Decipherer.decryptRSA(Decipherer.java:56) ~[getwechatmsg.jar:?] at com.pjcy.pullwechatmsg.Decipherer.decrypt(Decipherer.java:63) ~[getwechatmsg.jar:?] at com.pjcy.pullwechatmsg.ChatSet.decrypt(ChatSet.java:48) ~[getwechatmsg.jar:?] at com.pjcy.pullwechatmsg.Dispatcher.store(Dispatcher.java:57) ~[getwechatmsg.jar:?] at com.pjcy.pullwechatmsg.Dispatcher.start(Dispatcher.java:41) ~[getwechatmsg.jar:?]
故障原因排查方向
- 密文损坏:加密端输出的密文在传输/存储过程中被截断、篡改,或Base64编码包含无效字符(如多余空格、换行)
- 私钥异常:
getKeyString()返回的私钥内容被篡改、格式错误,或加载过程中出现编码问题 - 参数不匹配:加密端使用的填充模式、密钥对与解密端不一致(比如加密用了OAEPPadding而非PKCS1Padding)
- 环境/依赖变更:BouncyCastle版本被更新、JDK版本变更导致兼容性问题,或服务器安全策略调整限制了加密算法
- 密文长度不符:RSA密文长度应与密钥长度一致(如2048位密钥对应256字节密文),长度异常说明密文已损坏
解决思路
- 验证密文有效性
- 输出
encryptRandomKey的原始值,检查Base64解码后的字节长度是否匹配密钥长度;对比加密端生成的原始密文与解密端接收的内容是否完全一致
- 输出
- 确认私钥正确性
- 检查
getKeyString()返回的私钥内容是否与正常运行时一致,确保PEM格式规范;用OpenSSL命令验证私钥有效性:openssl rsa -check -in private.key
- 检查
- 核对加密解密参数
- 确认加密端使用的是
RSA/ECB/PKCS1Padding填充模式,且使用的公钥与解密端私钥属于同一密钥对
- 确认加密端使用的是
- 排查环境与依赖
- 确认BouncyCastle版本(当前为1.64)是否被改动,尝试回退至之前正常的版本;检查JDK版本是否变更,测试不同JDK环境下的运行情况
- 增加调试日志
- 在代码中添加日志,输出
encryptRandomKey的原始值、Base64解码后的字节数组长度、私钥加载后的密钥长度,进一步定位问题
- 在代码中添加日志,输出
内容的提问来源于stack exchange,提问作者sean
相关产品推荐
相关产品推荐

