Illegal key size 错误-JDK8版本JCE加密限制问题

Illegal key size 错误-JDK8版本JCE加密限制问题

1.问题

近期在开发公司微信开放平台时,使用第三方SDK的时候,出现了密码Illegal key size的错误。
具体代码环节如下:

  public String decrypt(String cipherText) {
    byte[] original;
    try {
      // 设置解密模式为AES的CBC模式
      Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
      SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
      IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(this.aesKey, 0, 16));
      cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);

      // 使用BASE64对密文进行解码
      byte[] encrypted = Base64.decodeBase64(cipherText);

      // 解密
      original = cipher.doFinal(encrypted);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    String xmlContent;
    String fromAppid;
    try {
      // 去除补位字符
      byte[] bytes = PKCS7Encoder.decode(original);

      // 分离16位随机字符串,网络字节序和AppId
      byte[] networkOrder = Arrays.copyOfRange(bytes, 16, 20);

      int xmlLength = bytesNetworkOrder2Number(networkOrder);

      xmlContent = new String(Arrays.copyOfRange(bytes, 20, 20 + xmlLength), CHARSET);
      fromAppid = new String(Arrays.copyOfRange(bytes, 20 + xmlLength, bytes.length), CHARSET);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    return xmlContent;

  }

在代码过程中的错误为:

java.security.InvalidKeyException: Illegal key size

2.排查

2.1 排查自身代码问题

代码本身经自己一步步断点调试,定位到这端AES解密代码.

2.2 排查环境问题

其实这才想起来,jdk也是有进口管制限制,所以JDK默认的加解密有一定的限制。

不允许 256 位密钥的 AES 加解密

这就是本质问题

3. 解决

方案与当前所用的JDK版本挂钩

3.1 若 jdk < 1.8.151

3.1.1 去oracle官方下载,JCE无限制文件。

Java6 (https://www.oracle.com/java/technologies/jce-6-download.html)
Java7 (https://www.oracle.com/java/technologies/javase-jce7-downloads.html)
Java8
(https://www.oracle.com/java/technologies/javase-jce8-downloads.html)

3.1.2 替换本地环境JDK以及JRE

local_policy.jar 以及US_export_policy.jar俩个文件覆盖本地{JDK_HOME}/jre/lib/security{JRE_HOME}/lib/security这个俩个文件里面的同名文件。

3.1.3 重启jvm应用

3.2 若 1.8.151 =< jdk < 1.8.161

3.2.1 修改security文件

当前版本为JVM启用无限制强度管辖策略,默认不启用。如果不启用此功能,则不能使用AES-256:文件夹位于{JDK_HOME}/jre/lib/security{JRE_HOME}/lib/security

3.2.2 修改java.security文件

打开java.security文件,搜索crypto.policy这一行。
默认值为limited,将其修改为非限制,如下。

crypto.policy=unlimited

3.2.3 重启jvm应用

3.3 若 1.8.161 =< jdk

不再限制密钥长度,所以也不会出现当前这个问题。

4. 总结

本质上是一个极小的问题,但是如果不了解或者不懂的善于利用网上资源,很容易浪费自己时间。其次,在自身代码的review上面,因为对第三方sdk的源码较熟,所以在排查问题第一步速度解决较快。最后,网上的各种解决方法太碎片化,毕竟毕竟通用的问题,我这儿结合了oracle的官方文档,更加简洁明朗的展示。加油~

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://blog.wyatt.plus/?p=41

Buy me a cup of coffee ☕.