解决128位秘钥长度限制的方法
Posted liuzhugu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解决128位秘钥长度限制的方法相关的知识,希望对你有一定的参考价值。
当秘钥长度超过128位(即16字符时),会加密失败,报“java.security.InvalidKeyException: Illegal key size or default parameters”的异常,因此需要去掉该限制
处理的方法由三种,分别是直接替换或是自定义classloader加载放开限制的jar或者通过反射移除限制
1.直接替换
比如java8的话,去orcle官网http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip下载,加载后解压将其中的“local_policy.jar ”和“US_export_policy.jar”两个文件替换掉自己%JAVE_HOME%jrelibsecurity文件夹下对应的原文件(%JAVE_HOME%是自己电脑的Java路径)
但现在一般是打包成镜像,部署在docker上,因此可以在dockerfile中加入下列配置来替换jar包
RUN yum install -y unzip zip RUN curl -q -L -C - -b "oraclelicense=accept-securebackup-cookie" -o /tmp/jce_policy-8.zip -O http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip && unzip -oj -d /opt/tuniu/jdk18/jre/lib/security /tmp/jce_policy-8.zip */*.jar && rm /tmp/jce_policy-8.zip
2.通过反射移除限制
在stackoverflow上看到解决方案,在加密前可以调用该方法
public static void fixKeyLength() { String errorString = "Failed manually overriding key-length permissions."; int newMaxKeyLength; try { if ((newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES")) < 256) { Class c = Class.forName("javax.crypto.CryptoAllPermissionCollection"); Constructor con = c.getDeclaredConstructor(); con.setAccessible(true); Object allPermissionCollection = con.newInstance(); Field f = c.getDeclaredField("all_allowed"); f.setAccessible(true); f.setBoolean(allPermissionCollection, true); c = Class.forName("javax.crypto.CryptoPermissions"); con = c.getDeclaredConstructor(); con.setAccessible(true); Object allPermissions = con.newInstance(); f = c.getDeclaredField("perms"); f.setAccessible(true); ((Map) f.get(allPermissions)).put("*", allPermissionCollection); c = Class.forName("javax.crypto.JceSecurityManager"); f = c.getDeclaredField("defaultPolicy"); f.setAccessible(true); Field mf = Field.class.getDeclaredField("modifiers"); mf.setAccessible(true); mf.setInt(f, f.getModifiers() & ~Modifier.FINAL); f.set(null, allPermissions); newMaxKeyLength = Cipher.getMaxAllowedKeyLength("AES"); } } catch (Exception e) { throw new RuntimeException(errorString, e); } if (newMaxKeyLength < 256) throw new RuntimeException(errorString); // hack failed }
3.自定义classloader
加密前只用自定义的classloader加载方法1中的jar包替换掉相应jar包
以上是关于解决128位秘钥长度限制的方法的主要内容,如果未能解决你的问题,请参考以下文章