异常: 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加密限制版本问题

posted @ 2023-08-06 19:47  strongmore  阅读(257)  评论(0编辑  收藏  举报