文章目录

一、发现现象

在用Java编写一个项目时,使用了AES作为数据库某些字段的加密方式,在Windows上正常运行,在Linux上调用AWS加密,抛出异常:

No installed provider supports this key: javax.crypto.spec.SecretKeySpec

二、问题根源

Java的政策文件限制了密钥长度。

JCE(Java Cryptography Extension)是Java的加密扩展包,由于美国对某些国家有进出口限制,因此低版本Java默认限制了密钥长度,比如AES加密只能使用16位AES-128,超过16位就会报这个错。

JDK8文档描述

Unlimited Strength Java Cryptography Extension
Due to import control restrictions for some countries, the Java Cryptography Extension (JCE) policy files shipped with the JDK and the JRE allow strong but limited cryptography to be used. These files are located at: <java-home>/lib/security/local_policy.jar <java-home>/lib/security/US_export_policy.jar where <java-home> is the jre directory of the JDK or the top-level directory of the JRE.

An unlimited strength version of these files indicating no restrictions on cryptographic strengths is available on the JDK web site for those living in eligible countries. Those living in eligible countries may download the unlimited strength version and replace the strong cryptography jar files with the unlimited strength files.

三、解决方法

1、Java版本<Java8u151

(1)去Oracle官网找到对应的政策解封jar包local_policy.jar和US_export_policy.jar

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 6

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 7

Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files 8

百度网盘全部下载(密码pmhg)

(2)覆盖$JAVA_HOME/jre/lib/security路径下对应的文件 

(3)重启Java应用程序

2、Java版本>=8u151且<8u161

(1)找到对应的安全描述文件

  • JDK:<java_home>/jre/lib/security/java.security
  • JRE:<java_home>/lib/security/java.security

(2)取消注释这一行,并保存

crypto.policy=unlimited

(3)重启JVM

3、Java版本>=8u161

例如Java8u161、Java9等,默认已经放开了这个JCE密钥长度限制。如果仍然发生报错,请检查java.security这个文件是否是最新的。

四、实际操作一下

1、下载java

https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.html下载多个版本的java,这里选择:

  • Java SE Development Kit 8u144
  • Java SE Development Kit 8u151
  • Java SE Development Kit 8u161

2、编写一个24密钥长度的AES加密类

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class Jce {

    public static byte[] AESEncode(String keySeed, String content){
        try {
            SecretKey key = new SecretKeySpec(keySeed.getBytes(), "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte [] byteEncode = content.getBytes("utf-8");
            byte [] result = cipher.doFinal(byteEncode);
            return result;
        } catch (Exception e) {
            System.out.println("error=" + e.getMessage());
        }
        return null;
    }

    public static void main(String[] args) {
        byte[] result = Jce.AESEncode("abcdefghijklmnopqrstuvwx", "testContent");
        System.out.println("result=" + new String(result));
    }

}

3、使用对应的java版本编译和执行

# 编译成class文件
javac Jce.java
# 执行
java Jce

4、观察结果和按照对应方案调整

(1)8u144编译和执行,失败

root@ubuntu:/home/bwb/Desktop# jdk1.8.0_144/bin/javac Jce.java
root@ubuntu:/home/bwb/Desktop# jdk1.8.0_144/bin/java Jce
error=Illegal key size or default parameters
Exception in thread "main" java.lang.NullPointerException
	at java.lang.String.<init>(String.java:566)
	at Jce.main(Jce.java:23)

(2)8u144替换jar后再次执行,成功

root@ubuntu:/home/bwb/Desktop# jdk1.8.0_144/bin/java Jce
result=(这里是乱码,不展示了)

(3)8u151编译和执行,失败

root@ubuntu:/home/bwb/Desktop# jdk1.8.0_151/bin/javac Jce.java
root@ubuntu:/home/bwb/Desktop# jdk1.8.0_151/bin/java Jce
error=Illegal key size or default parameters
Exception in thread "main" java.lang.NullPointerException
	at java.lang.String.<init>(String.java:566)
	at Jce.main(Jce.java:23)

(4)8u151修改security.java后执行,成功

root@ubuntu:/home/bwb/Desktop# jdk1.8.0_151/bin/java Jce
result=(这里是乱码,不展示了)

(5)8u161直接编译和执行,成功

root@ubuntu:/home/bwb/Desktop# jdk1.8.0_161/bin/javac Jce.java
root@ubuntu:/home/bwb/Desktop# jdk1.8.0_161/bin/java Jce
result=(这里是乱码,不展示了)


该问题和解决方法已录入Wiki:《No installed provider supports this key SecretKeySpec》


转载请注明出处http://www.bewindoweb.com/290.html | 三颗豆子
分享许可方式知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
重大发现:转载注明原文网址的同学刚买了彩票就中奖,刚写完代码就跑通,刚转身就遇到了真爱。
你可能还会喜欢
具体问题具体杠