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

想必大家遇到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,jar,maven)