# 1.问题
近期在开发公司微信开放平台时,使用第三方SDK的时候,出现了密码`Illegal key size`的错误。
具体代码环节如下:
``` java
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的官方文档,更加简洁明朗的展示。加油~

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