JDK11 使用AES加密时报java.security.InvalidKeyException: Illegal key size【已解决】

背景

公司项目集成钉钉API时回调接口需要使用32位长(258bit)密钥解密服务器回传的加密信息,在代码执行至cipher.init(2, keySpec, iv)时报java.security.InvalidKeyException: Illegal key size错误。

try {
            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(2, keySpec, iv);
            networkOrder = Base64.decodeBase64(text);
            originalArr = cipher.doFinal(networkOrder);
        } catch (Exception var9) {
            throw new DingTalkEncryptException(900008);
        }

解决方案

google到一系列文章提到jdk1.8前 java运行时环境读到的是受限的policy文件,限制了AES加密的密钥长度,需要下载载JCE无限制权限策略文件,原文引用如下:

异常原因:如果密钥大于128, 会抛出java.security.InvalidKeyException: Illegal key size 异常. 因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件. 文件位于${java_home}/jre/lib/security, 这种限制是因为美国对软件出口的控制.
解决方案:去官方下载JCE无限制权限策略文件。
jdk 5: http://www.oracle.com/technetwork/java/javasebusiness/downloads/java-archive-downloads-java-plat-419418.html#jce_policy-1.5.0-oth-JPR
jdk6: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
JDK7的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
JDK8的下载地址: http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt
如果安装了JRE,将两个jar文件放到%JRE_HOME%\lib\security目录下覆盖原来的文件
如果安装了JDK,还要将两个jar文件也放到%JDK_HOME%\jre\lib\security目录下覆盖原来文件。
侵删,引用自https://www.cnblogs.com/lilinzhiyu/p/8024100.html

但我项目中使用的JDK为11.0.12,尝试了上述方法发现没有解决问题,遂跟踪了一下代码,一直跟踪到JceSecurity.class的setupJurisdictionPolicies方法下,发现上述限制来自于jdk-11.0.12\conf\security\policy\limited\default_local.policy文件最后一行,遂将最后一行permission javax.crypto.CryptoPermission *, 128修改为permission javax.crypto.CryptoPermission *, 512; 顺利解决。

// Some countries have import limits on crypto strength. This policy file
// is worldwide importable.

grant {
    permission javax.crypto.CryptoPermission "DES", 64;
    permission javax.crypto.CryptoPermission "DESede", *;
    permission javax.crypto.CryptoPermission "RC2", 128, 
                                     "javax.crypto.spec.RC2ParameterSpec", 128;
    permission javax.crypto.CryptoPermission "RC4", 128;
    permission javax.crypto.CryptoPermission "RC5", 128, 
          "javax.crypto.spec.RC5ParameterSpec", *, 12, *;
    permission javax.crypto.CryptoPermission "RSA", *;
    // permission javax.crypto.CryptoPermission *, 128;
    permission javax.crypto.CryptoPermission *, 512;
};

总结

1、限制来源于jdk-11.0.12\conf\security\policy\limited\default_local.policy文件。
2、在代码中通过Security.setProperty(“crypto.policy”, “limited”)指定配置文件,并修改default_local.policy中最后一行的128为512顺利解决。

参考https://donaldhan.github.io/java/2020/08/07/JCE%E5%8A%A0%E5%AF%86%E6%9C%BA%E5%88%B6%E7%9A%84%E4%B8%80%E6%AC%A1%E5%A1%AB%E5%9D%91.html

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值