JDK11中AES/CTR/PKCS5PADDING可用,JDK17报错的解决方法
JDK17中AES/CTR/PKCS5PADDING组合报错问题解决
问题背景
给定以下代码:
byte[] lDecoded = Base64.getDecoder().decode(pValueBase64Encoded); Cipher lCipher = Cipher.getInstance("AES/CTR/PKCS5PADDING");
在JDK17中调用Cipher.getInstance()时抛出异常:
Exception in thread "main" java.security.NoSuchAlgorithmException: Cannot find any provider supporting AES/CTR/PKCS5PADDING at java.base/javax.crypto.Cipher.getInstance(Cipher.java:571) Pop3Handler.main(Pop3Handler.java:81) Caused by: javax.crypto.NoSuchPaddingException: CTR mode must be used with NoPadding at java.base/com.sun.crypto.provider.CipherCore.setPadding(CipherCore.java:258) at java.base/com.sun.crypto.provider.AESCipher.engineSetPadding(AESCipher.java:206) at java.base/javax.crypto.Cipher$Transform.setModePadding(Cipher.java:388) at java.base/javax.crypto.Cipher.getInstance(Cipher.java:564) ... 4 more
但该代码在JDK11中可正常运行。
为排查问题,编写测试代码检查加密提供者支持的模式和填充:
@Test public void testProviders() { Provider[] provs = Security.getProviders(); for (Provider provider : provs) { Service service = provider.getService("Cipher", "AES"); if (service == null) { continue; } String modes = service.getAttribute("SupportedModes"); if (modes != null && modes.matches("(?i).*CTR.*")) { System.out.println("CTR found:"); System.out.println(service); } else { System.out.println("CTR NOT found:"); } String paddings = service.getAttribute("SupportedPaddings"); if (paddings != null && paddings.matches("(?i).*PKCS5PADDING.*")) { System.out.println("PKCS5PADDING found:"); System.out.println(service); } else { System.out.println("PKCS5PADDING NOT found:"); } } }
JDK17测试输出:
CTR found: SunJCE: Cipher.AES -> com.sun.crypto.provider.AESCipher$General aliases: [OID.2.16.840.1.101.3.4.1, 2.16.840.1.101.3.4.1] attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB|CBC|PCBC|CTR|CTS|CFB|OFB|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128, SupportedPaddings=NOPADDING|PKCS5PADDING|ISO10126PADDING} PKCS5PADDING found: SunJCE: Cipher.AES -> com.sun.crypto.provider.AESCipher$General aliases: [OID.2.16.840.1.101.3.4.1, 2.16.840.1.101.3.4.1] attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB|CBC|PCBC|CTR|CTS|CFB|OFB|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128, SupportedPaddings=NOPADDING|PKCS5PADDING|ISO10126PADDING}
JDK11测试输出:
CTR found: SunJCE: Cipher.AES -> com.sun.crypto.provider.AESCipher$General aliases: [Rijndael] attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB|CBC|PCBC|CTR|CTS|CFB|OFB|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64|GCM|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128, SupportedPaddings=NOPADDING|PKCS5PADDING|ISO10126PADDING} PKCS5PADDING found: SunJCE: Cipher.AES -> com.sun.crypto.provider.AESCipher$General aliases: [Rijndael] attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB|CBC|PCBC|CTR|CTS|CFB|OFB|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64|GCM|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128, SupportedPaddings=NOPADDING|PKCS5PADDING|ISO10126PADDING}
从输出看,CTR模式和PKCS5PADDING均被支持,但组合使用时JDK17报错,该如何解决?
解决方案
本质原因:CTR属于流密码模式,这类模式本身要求明文长度是分组大小的整数倍,不需要额外填充。JDK11之前的SunJCE提供者没有严格校验这种非法组合,允许了
AES/CTR/PKCS5PADDING的存在,但这不符合密码学规范。JDK17开始严格遵循规范,禁止了这种错误组合。正确的修改方式:将Cipher实例化的代码改为使用
NoPadding:Cipher lCipher = Cipher.getInstance("AES/CTR/NoPadding");同时需要确保:
- 加密时,明文长度必须是AES分组大小(16字节)的整数倍;如果原代码依赖PKCS5Padding自动填充,需要在加密逻辑中手动处理明文填充,再使用CTR模式加密。
- 解密时,先通过CTR模式解密,再手动移除填充(如果原加密数据带PKCS5Padding的话)。
兼容JDK11和JDK17的临时方案(不推荐):如果暂时无法修改加密逻辑,可以指定使用BouncyCastle等第三方加密提供者,这类提供者可能允许这种非规范组合。但这种方式不符合密码学最佳实践,存在安全风险,不建议长期使用:
// 需先引入BouncyCastle依赖 Cipher lCipher = Cipher.getInstance("AES/CTR/PKCS5PADDING", "BC");
内容的提问来源于stack exchange,提问作者cilap
相关产品推荐
相关产品推荐

