Java使用RSA_PKCS1_OAEP_PADDING加密报NoSuchPaddingException解决方法
问题根因
抛出javax.crypto.NoSuchPaddingException: RSA/ECB/OAEPPadding unavailable with RSA是因为传入Cipher.getInstance()的算法转换字符串和当前指定Provider支持的命名规则不匹配。RSA_PKCS1_OAEP_PADDING是PKCS#1 v2.0标准定义的填充模式,不同JCE安全提供者对该算法的命名规则存在差异,未带完整参数的简写RSA/ECB/OAEPPadding仅在特定Provider的特定版本下被支持,通用性极差。
正确实现方式
- 使用JDK内置SunJCE提供者(默认场景,无需引入第三方依赖)
必须写全OAEP填充的参数声明,不支持无参数的OAEPPadding简写。对应标准RSA_PKCS1_OAEP_PADDING(默认采用SHA-1作为哈希函数、MGF1作为掩码生成函数)的正确写法如下:
如果需要使用更高强度的SHA-256等哈希算法,直接替换参数即可:// 无需手动指定provider,默认使用SunJCE,全JDK版本兼容 Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");// OAEP填充使用SHA-256哈希,MGF1对应使用SHA-256 Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); - 使用BouncyCastle第三方提供者
若项目已引入并注册BouncyCastle,除了上述标准全写方式外,高版本BC支持OAEPPadding简写,但必须明确指定提供者名称为BC,否则仍会抛出异常:// 先注册BC提供者 Security.addProvider(new BouncyCastleProvider()); // 明确指定BC提供者才能使用简写,生产环境不推荐该写法,兼容性差 Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding", "BC");
注意事项
- 转换字符串中的
ECB是Java Cipher API的固定格式要求,RSA属于非对称加密算法,没有分组加密的ECB模式语义,不存在ECB模式的安全风险,无需修改该字段。 - 加密、解密两端必须使用完全一致的OAEP配置,包括哈希算法、MGF1参数,否则会出现填充校验失败、解密结果错误的问题。
- 避免跨提供者混用算法实现,例如加密端使用SunJCE的OAEP实现、解密端使用不同参数配置的BC实现,大概率会触发填充不匹配异常。
内容的提问来源于stack exchange,提问作者tian-xiaocai
相关产品推荐
相关产品推荐

