解决因jdk版本问题不支持aes256加密问题(Illegal key size or default parameters)

该博客介绍了如何通过反射方式解决在Java中使用AES256加密时遇到的`java.security.InvalidKeyException: Illegal key size or default parameters`异常,避免替换JDK政策文件带来的潜在风险。文章提供了详细代码示例,演示了针对不同JDK版本解除128位限制的方法,并给出注意事项和参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

想必大家遇到aes256加密报如下异常:java.security.InvalidKeyException: Illegal key size or default parameters,在网上搜到最多的解决方案是在oracle官网下载补丁jar包(local_policy.jar、US_export_policy.jar),进行替换。
当然,如果这个一个新项目,或者项目规模较小,完全可以通过替换对应jar包,或者升级jdk的版本来解决。但对于一个规模较大,稳定运行的项目,替换jar包可能意味着将系统推向潜在的未知的风险。
下面,通过反射来修改jdk对aes加密可以长度的限制

需要注意的是不同版本的jdk在实现有界限制的代码存在差异

测试jdk版本
此处使用openjdk

D:\test\springWorkspace>java -version
openjdk version "1.8.0_41"
OpenJDK Runtime Environment (build 1.8.0_41-b04)
OpenJDK Client VM (build 25.40-b25, mixed mode)

上实现代码

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.security.NoSuchAlgorithmException;
import java.security.Permission;
import java.security.PermissionCollection;
import java.util.Map;

import javax.crypto.Cipher;

import org.junit.jupiter.api.Test;

/**
 * @author liujun
 * @since 2022/5/17
 */
public class TestAes {

    /**
     * 去除jdk的128位的限制
     */
    public static void removeCryptographyRestrictions() {
        try {
            /*
             * Do the following, but with reflection to bypass access checks:
             * JceSecurity.isRestricted = false;
             * JceSecurity.defaultPolicy.perms.clear();
             * JceSecurity.defaultPolicy.add(CryptoAllPermission.INSTANCE);
             */
            final Class<?> jceSecurity = Class.forName("javax.crypto.JceSecurity");
            final Class<?> cryptoPermissions = Class.forName("javax.crypto.CryptoPermissions");
            final Class<?> cryptoAllPermission = Class.forName("javax.crypto.CryptoAllPermission");

            final Field isRestrictedField = jceSecurity.getDeclaredField("isRestricted");
            isRestrictedField.setAccessible(true);
            // 去除isRestricted的final限制
            final Field modifiersField = Field.class.getDeclaredField("modifiers");
            modifiersField.setAccessible(true);
            modifiersField.setInt(isRestrictedField, isRestrictedField.getModifiers() & ~Modifier.FINAL);
            isRestrictedField.set(null, false);

            final Field defaultPolicyField = jceSecurity.getDeclaredField("defaultPolicy");
            defaultPolicyField.setAccessible(true);
            final PermissionCollection defaultPolicy = (PermissionCollection) defaultPolicyField.get(null);

            final Field perms = cryptoPermissions.getDeclaredField("perms");
            perms.setAccessible(true);
            ((Map<?, ?>) perms.get(defaultPolicy)).clear();

            final Field instance = cryptoAllPermission.getDeclaredField("INSTANCE");
            instance.setAccessible(true);
            defaultPolicy.add((Permission) instance.get(null));

        } catch (final Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    public void testGetLength() throws NoSuchAlgorithmException {
        long length = Cipher.getMaxAllowedKeyLength("AES");
        System.out.println("before:" + length);

        removeCryptographyRestrictions();

        length = Cipher.getMaxAllowedKeyLength("AES");
        System.out.println("after:" + length);
    }

}

输出

before:128
after:2147483647

需要注意的点
对于部分jdk版本"javax.crypto.JceSecurity"下的isRestricted是非final限制的,所以不需要额外处理去除final限制的代码。

参考文档:
https://stackoverflow.com/questions/1179672/how-to-avoid-installing-unlimited-strength-jce-policy-files-when-deploying-an
————————————————
原文链接:https://blog.csdn.net/weixin_39265427/article/details/106505502

### 解决 Java `InvalidKeyException`: "Illegal key size or default parameters" 错误 当遇到`java.security.InvalidKeyException: Illegal key size or default parameters`错误时,通常是因为使用的密钥长度超过了默认策略文件允许的最大值[^1]。 #### 密钥大小限制的原因 Java 加密扩展 (JCE) 默认安装的安全策略文件只支持有限强度的加密算法。对于 AES 来说,默认情况下仅支持最大到 128 位的密钥长度。如果尝试使用更长的密钥,则会触发上述异常[^2]。 #### 安装无限制权限策略文件 要解决这个问题,可以下载并替换 JRE 中的标准本地政策 jar 文件为不受限版本: - 访问 Oracle 官方网站获取适用于当前 JDK 版本的 **Unlimited Strength Jurisdiction Policy Files** - 将下载得到的两个 jar 文件覆盖至 `$JAVA_HOME/jre/lib/security` 目录下相应位置[^3] 完成此操作之后重启应用程序应该能够正常使用较大尺寸的密钥而不再抛出该异常。 #### 验证解决方案的有效性 可以通过编写简单的测试程序来验证问题是否已经解决: ```java import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; public class TestAES { public static void main(String[] args)throws Exception{ KeyGenerator kg = KeyGenerator.getInstance("AES"); kg.init(256); // 使用256位密钥 SecretKey sk = kg.generateKey(); Cipher cipher = Cipher.getInstance("AES"); cipher.init(Cipher.ENCRYPT_MODE,sk); System.out.println("Test passed!"); } } ``` 成功运行这段代码意味着现在可以在项目里安全地采用更高强度的加密方式了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值