Java的AES加解密异常java.security.InvalidKeyException: Illegal key size 的解决方法

项目场景:

通过微信商家转账到零钱(v3接口)需要从微信后台下载证书文件,下载完成后需要使用32位(128bit)密钥通过AES解密证书信息,最后写入文件保存。


问题描述

今天线上出现java.security.InvalidKeyException: Illegal key size异常,经排查测试,配置无任何问题,在开发环境运行,可以正常下载解密证书文件信息。

Caused by: java.security.InvalidKeyException: Illegal key size
	at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1039)
	at javax.crypto.Cipher.implInit(Cipher.java:805)
	at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
	at javax.crypto.Cipher.init(Cipher.java:1396)
	at javax.crypto.Cipher.init(Cipher.java:1327)
	at com.wechat.pay.contrib.apache.httpclient.util.AesUtil.decryptToString(AesUtil.java:40)
	...

原因分析:

我们需要要了解一个新的东西——JCE。在Java的核心类库中有一个JCE(Java Cryptography Extension),JCE是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现,所以这个是实现加密解密的重要类库。
在Linux环境中出现java.security.InvalidKeyException: Illegal key size异常通常是由于Java默认的加密限制引起的。Java默认的加密强度限制了加密算法密钥的最大长度。
因为JDK受版本安全限制,默认只允许128位长度以内的秘钥长度,如果密钥大于128位, 会抛出java.security.InvalidKeyException: Illegal key size 异常。
java运行时环境默认读到的是受限的policy文件,文件位于${JAVA_HOME}/jre/lib/security,这种限制是因为美国对软件出口的控制所造成的,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制,JDK1.8之后已经兼容了该问题。


解决方案:

1.升级不受限制的JDK版本

将jdk版本升级到jdk9及以上。

2.替换JCE无限制权限策略文件

去官方下载JCE无限制权限策略文件。
JDK5的下载地址: Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 5 Download
JDK6的下载地址:Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6 Download
JDK7的下载地址: Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7 Download
JDK8的下载地址: Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8 Download
下载后解压,可以看到local_policy.jar和US_export_policy.jar以及readme.txt文件。
如果安装了JRE,将两个jar文件放到${JAVA_HOME}\lib\security目录下覆盖原来的文件。
如果安装了JDK,还要将两个jar文件也放到${JAVA_HOME}\jre\lib\security目录下覆盖原来文件。

3.JDK1.8 代码策略修改

部分高版本JDK1.8已经支持不受限的jar,但配置默认是受限的

JDK安装目录
方法一:

  1. 找到Java安装目录下的jre/lib/security文件夹。根据你的具体安装,这个路径可能会有所不同。
  2. security文件夹中,找到名为java.security的文件,备份该文件。
  3. 使用文本编辑器打开java.security文件。
  4. 在文件中找到以下行(可能位于文件的底部),如下所示:

#crypto.policy=unlimited

将其取消注释,修改为:

crypto.policy=unlimited

这将启用无限制的加密策略。

  1. 保存并关闭java.security文件。
  2. 重新运行你的Java程序,应该不再出现java.security.InvalidKeyException: Illegal key size异常。这样做将解除Java对加密强度的限制,允许使用更长的密钥。

请注意,修改Java加密策略可能会涉及到安全性问题。在进行修改之前,请确保你对系统安全性的评估,并确保你的系统在其他方面也有适当的安全措施。

方法二:
修改代码配置,在加解密之前,修改不受限制配置,如下所示:

public String decryptToString(byte[] associatedData, byte[] nonce, String ciphertext)
            throws GeneralSecurityException {
        try {
        	//修改为不受限制
        	Security.setProperty("crypto.policy", "unlimited");
        	
            SecretKeySpec key = new SecretKeySpec(aesKey, "AES");
            GCMParameterSpec spec = new GCMParameterSpec(TAG_LENGTH_BIT, nonce);

            Cipher cipher = Cipher.getInstance(TRANSFORMATION);
            cipher.init(Cipher.DECRYPT_MODE, key, spec);
            cipher.updateAAD(associatedData);
            return new String(cipher.doFinal(Base64.getDecoder().decode(ciphertext)), StandardCharsets.UTF_8);

        } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
            throw new IllegalStateException(e);
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            throw new IllegalArgumentException(e);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值