异常: 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无限制权限策略文件,将两个jar文件放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。JDK8的下载地址
或者减少format长度
private static byte[] formatData(byte[] data) {
return DigestUtils.md5(data);
}
参考
异常: java.security.InvalidKeyException: Illegal key size