一、错误信息
您正在使用Java加密扩展开发漂亮的应用程序,并且使用长度超过128位的密钥时,您会遇到以下错误:
Caused by: java.security.InvalidKeyException: Illegal key size or default parameters
您所做的一切都是正确的:JDK在默认情况下有一个专门的密钥大小限制,因此您不能使用密钥超过128位的加密。
Java官方文档:Oracle’s documentation。
二、错误原因
其实,Java几乎各种常用加密算法都能找到对应的实现。但是因为美国的出口限制,Sun通过权限文件(local_policy.jar、US_export_policy.jar)做了相应限制。因此存在一些问题:
- 密钥长度上不能满足需求(如:java.security.InvalidKeyException: Illegal key size or default parameters);
- 部分算法未能支持,如MD4、SHA-224等算法;
- API使用起来还不是很方便;一些常用的进制转换辅助工具未能提供,如Base64编码转换、十六进制编码转换等工具。
Oracle在其官方网站上提供了无政策限制权限文件(Unlimited Strength Jurisdiction Policy Files),我们只需要将其部署在JRE环境中,就可以解决限制问题。
由于一些国家政府的进口控制限制,Sun Microsystems提供的JDK 5.0附带的管辖政策文件指定可以使用“强”但有限的加密。
有些国家对加密算法使用的允许密钥强度有限制:
这些文件的“无限强度”版本表明对密码强度没有限制,适用于居住在合格国家(即大多数国家)的人。但只有“强大”的版本才能被输入那些政府强制限制的国家。JCE框架将强制执行已安装的管辖权策略文件中指定的限制。
三、解决方案
那么,如何删除密钥的大小限制呢?
方法1:通过反射进行修改
/** * 1、通过反射去除JCE加密限制,此方法只限于Java1.8,直接复制(可能报错,引用java.lang.reflect下的包即可) * 2、在main方法中加密操作之前调用一下这个方法就OK了 */ private static void removeJceLimit() { try { Field field = Class.forName("javax.crypto.JceSecurity").getDeclaredField("isRestricted"); field.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); modifiersField.setAccessible(true); modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); field.set(null, false); log.info("============= remove the key size restriction Success ============="); } catch (ClassNotFoundException | NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) { ex.printStackTrace(System.err); } }
注意:使用方法1,解决这个问题的时候,自测加密是可以的,但是,在解密的时候 还会报错,所以最稳妥的办法还是方法2。
方法2:下载官方Jar包修改
您可以使用无限制强度的策略jar替换现有的JCE jar,从而消除最大密钥限制(JAVA官网提供两个版本的Jar包,以下是官网下载地址):
1、对于Java 5 的JCE jar包下载地址如下:Java 5.0 无政策限制文件
2、对于Java 6 的JCE jar包下载地址如下:Java 6 无政策限制文件
3、对于Java 7 的JCE jar包下载地址如下:Java 7 无政策限制文件
4、对于Java 8 的JCE jar包下载地址如下:Java 8 无政策限制文件
5、对于Java 其他版本 的JCE jar包下载地址如下:其他版本 无政策限制文件
将上面zip文件中提取的local_policy.jar和US_export_policy.jar复制到$JAVA_HOME/jre/lib/security。
然后只需重新启动java应用程序,异常就会消失。
具体步骤:
1、下载的压缩包中仅有一个目录,也就是jce目录。该目录中包含了4个文件:README.txt、COPYRIGHT.html、local_policy.jar和US_export_policy.jar。其中包含的两个jar文件正是此次配置中用到的文件。
2、我们可以查看上述README.txt文件,你需要在JDK的JRE环境中,或者是JRE环境中配置上述两个jar文件。
3、切换到%JDK_Home%\jre\lib\security目录下,对应覆盖local_policy.jar和US_export_policy.jar两个文件。同时,你可能有必要在%JRE_Home%\lib\security目录下,也需要对应覆盖这两个文件。
4、配置权限文件的最终目的是为了使应用在运行环境中获得相应的权限,可以加强应用的安全性。通常,我们在应用服务器上安装的是JRE,而不是JDK。所以很有必要在应用服务器的%JRE_Home%\lib\security目录下,对应覆盖这两个权限文件。
【参考资料】
Andrea Fortuna:https://www.andreafortuna.org/2016/06/08/java-tips-how-to-fix-the-invalidkeyexception-illegal-key-size-or-default-parameters-runtime/