异常: java.security.InvalidKeyException: Illegal key size
问题描述
import org.apache.commons.codec.digest.DigestUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.security.Security;
import java.util.Base64;
public class TestAES {
public static void main(String[] args) throws Exception {
System.out.println(encrypt("abc".getBytes()));
}
private static String encrypt(byte[] data) throws Exception {
byte[] enCodeFormat = formatData(data);
//根据给定的字节数组构造一个密钥。enCodeFormat:密钥内容;"AES":与给定的密钥内容相关联的密钥算法的名称
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//将提供程序添加到下一个可用位置
Security.addProvider(new BouncyCastleProvider());
//创建一个实现指定转换的 Cipher对象,该转换由指定的提供程序提供。
//"AES/ECB/PKCS7Padding":转换的名称;"BC":提供程序的名称
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] bytes = cipher.doFinal(enCodeFormat);
return Base64.getEncoder().encodeToString(bytes);
}
private static byte[] formatData(byte[] data) {
return DigestUtils.sha256(data);
}
}
代码出现异常
Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1029)
at javax.crypto.Cipher.implInit(Cipher.java:804)
at javax.crypto.Cipher.chooseProvider(Cipher.java:867)
at javax.crypto.Cipher.init(Cipher.java:1252)
at javax.crypto.Cipher.init(Cipher.java:1189)
at com.example.demo.TestAes256.encrypt(TestAes256.java:26)
at com.example.demo.TestAes256.main(TestAes256.java:13)
问题原因
如果密钥大于128, 会抛出java.security.InvalidKeyException: Illegal key size 异常. 因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件. 文件位于${java_home}/jre/lib/security, 这种限制是因为美国对软件出口的控制.
解决方案
去官方下载JCE无限制权限策略文件(local_policy.jar和US_export_policy.jar),将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。JDK8的下载地址
或者减少format长度
private static byte[] formatData(byte[] data) {
return DigestUtils.md5(data);
}
从Java 1.8.0_151和1.8.0_152开始,JVM启用无限制强度管辖策略 有了一种新的更简单的方法。
在 jre/lib/security 文件夹中找到文件 java.security,并找到定义java安全性属性crypto.policy的行,它可以有两个值limited或unlimited - 默认值是limited。将其设置为:
crypto.policy=unlimited
参考
异常: java.security.InvalidKeyException: Illegal key size
关于JDK8采坑JCE加密限制版本问题