Bouncy Castle与Java默认RSA OAEP解密报错及模式差异问询
BadPaddingException的原因及转换差异解析 核心问题:加密与解密的算法配置不匹配
你的代码抛出异常的根本原因是加密和解密的Cipher配置不完全一致,具体有两个关键差异:
密码提供者不一致
加密时你明确指定了Bouncy Castle("BC")作为算法提供者,但解密时没有指定提供者,会默认使用JVM自带的提供者(比如SunJCE)。不同密码提供者对RSA OAEP算法的实现细节、参数默认值可能存在细微差异,哪怕算法名称看起来相似,也会导致解密时无法正确解析填充内容。算法字符串的精确匹配问题
加密用的是"RSA/NONE/OAEPWithSHA256AndMGF1Padding",解密用的是"RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"——虽然填充规则描述相似,但不同提供者对算法名称的解析是严格区分的,大小写、连字符的使用差异,都会影响算法的加载逻辑,导致实际使用的加密规则不匹配。
关于RSA ECB/NONE命名的疑问解答
你引用的那段表述确实适用于RSA OAEP:
"RSA/ECB/PKCS1Padding"实际上并未实现ECB模式加密。它本应被命名为"RSA/None/PKCS1Padding",因为它仅能加密单个明文块(或密钥)。这只是Sun/Oracle的命名错误。
RSA本身是基于固定长度单块的非对称加密,所谓的ECB模式只是历史遗留的命名错误,和对称加密的ECB模式完全不是一回事,RSA/ECB/...和RSA/NONE/...在语义上确实等效,都是单块加密逻辑。
那为什么你的测试没通过?因为这个命名等效性只在同一提供者内部成立,跨提供者的话,再加上算法字符串的格式差异,就会打破这种等效性,最终导致解密失败。
修复方案
要解决这个问题,只需要让加密和解密的Cipher配置完全一致即可,有两种可行方式:
- 方式一:解密时也指定Bouncy Castle提供者,并且使用和加密完全相同的算法字符串:
Cipher decryptionCipher = Cipher.getInstance("RSA/NONE/OAEPWithSHA256AndMGF1Padding", "BC");
- 方式二:统一使用默认提供者的算法字符串(需确保默认提供者支持该算法),加密和解密保持写法一致:
// 加密时也使用默认提供者的算法名 Cipher encryptionCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING"); // 解密保持不变 Cipher decryptionCipher = Cipher.getInstance("RSA/ECB/OAEPWITHSHA-256ANDMGF1PADDING");
额外补充:RSA OAEP的安全性依赖于哈希函数和MGF1函数的一致性,如果你需要更精细的控制,可以通过OAEPParameterSpec手动指定哈希算法和MGF1参数,确保加密和解密的参数完全匹配。
内容的提问来源于stack exchange,提问作者Martin Dow

