项目场景:
  新上线一个功能,其中需要在某模块对请求中的某个加密数据进行解码,

  加密方式通过AES加密法进行加密。

  需要借助javajdk的javax.crypto包下的加密工具进行解密。

问题描述:
  在本机写单测进行加密数据解密测试,解密成功

  但是进行线上完整请求测试时,却发现相关加密数据无法正常入库,数据链路存在问题。

  修改相关模块日志等级,拉取完整请求各个负责模块的相关日志,监控是否有接收到相关数据信息;

  经过一番折腾与不断测试,终于锁定问题模块,并发现以下异常:

java.security.InvalidKeyException: No installed provider supports this key: javax.crypto.spec.SecretKeySpec
1
  对问题进行剖析,定义问题根源,发现并不是解析传入的加密数据时出现问题,而是在相关解密钥匙初始化时就出现问题。根据异常信息提示,这是解密的密钥出现问题。

原因分析:
  经过观察分析,发现这是解密的密钥key有问题。网上检索相关异常后发现问题产生原因:

  因为美国法律限制,JAVA默认支持AES 128 Bit 的key,如果密钥大于128 Bit, 会抛出java.security.InvalidKeyException: Illegal key size 异常. 因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件. 文件位于${java_home}/jre/lib/security, 这种限制是因为美国对软件出口的控制。

  对比本机jdk与线上环境jdk版本,发现均为jdk1.8版本。为什么本机就可以正常解码,而线上的jdk1.8就不行呢?

解决方案:
  经过长时间检索原因,查询网上博客、官方文档,最后终于找到以下几种解决方法:

下载 JCE无限制权限策略文件,替换%JAVA_HOME%/jre/lib/security下的local_policy.jar 和 US_export_policy.jar;
1.6版本

http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html

1.7版本

http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html

1.8版本:

http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html

pom文件中引入第三方jar包,利用第三方jar包进行解码;
        <dependency>
            <groupId>org.bouncycastle</groupId>
            <artifactId>bcprov-jdk15on</artifactId>
            <version>1.56</version>
        </dependency>

1
2
3
4
5
6
升级jdk1.8的版本到1.8.0_162以上,此时默认是支持AES256解码的。该方法思路来自以下这段话,同时这也是对同版本jdk却产生行为的不同结果的解释。
To solve that you have to go to this website, download the Unlimited
Strength Jurisdiction Policy Files, unzip it, go to the
/lib/security directory, and replace the two files
local_policy.jar and US_export_policy.jar with the two files from the
download.

Starting with Java 1.8.0_151 and 1.8.0_152 there is a new somewhat
easier way to enable the unlimited strength jurisdiction policy for
the JVM. Without enabling this you cannot use AES-256. Since this
version, it is no longer necessary to download the policy files from
the Oracle website and install it. You can now set the unlimited
policy directly in your application with this one-liner:
Security.setProperty(“crypto.policy”, “unlimited”);

In Java 1.8.0_162, the unlimited policy is enabled by default. You no
longer need to install the policy file in the JRE or set the security
property crypto.policy.

  敲定具体解决方案:
   经过与同事间的讨论,最终敲定方案三。理由如下:

方案一:对原生jdk直接进行修改,对线上java程序而言,风险性过大。op方也很难同意这种要求。
方案二:第三方包的引入风险同样很大,无法确定第三方包本身的
安全性、可靠性。
方案三:jdk版本的升级,而且是小版本的升级,是大家都比较能接受的,对企业安全也没有造成其他威胁性。
————————————————
版权声明:本文为CSDN博主「2年半个人练习生」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43717407/article/details/119011685

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐