2021年8月20日-AES加解密问题

688 阅读2分钟

环境

我的本地测试环境:windows 10 64位

公司服务器测试环境:Red Hat 4.8.5-28

问题描述:

对接三方公司的时候,对方使用AES格式对数据进行加密,传到我司后需要进行解密。密钥已经给到我司,以及相关的加/解密工具类,但是测试的时候发现在我自己电脑上使用三方公司传递的加密报文测试,使用其工具类可以正常解密,但是一旦使用我司测试环境的服务,就发现三方公司的工具类的解密方法抛空指针异常。

抱着各种侥幸心里(三方公司的工具类怎么可能出现错误,毕竟人家不止你一个使用),然后就是各种查自己的代码哪里传值不对,然并卵。

尝试了许久后,此时已经是第二天早上了,晚上搞了一晚上。最终还是向着三方公司给的工具类“杀”过去,在解密方法中加了许多打印,基本快一行一个log.info了,但是偏偏没在它捕获的异常里添加log.info,每次返回一个java.lang.NullPointerException,高于三方公司的捕获异常,一直没打印出来,后面加上打印日志后,发现最终异常是:BadPaddingException

网上查了一下:

发现最终的问题出在:

kgen.init(128, new SecureRandom(key.getBytes()));//该行在linux下出现问题

原因是因为:SecureRandom 实现完全随操作系统本身的內部状态,除非调用方在调用 getInstance 方法,然后调用 setSeed 方法;该实现在 windows 上每次生成的 key 都相同,但是在 solaris部分 linux 系统上则不同。

所以需要将new SecureRandom()改为如下代码:

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
secureRandom.setSeed(password.getBytes());
KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者

new SecureRandomSecureRandom.getInstance("SHA1PRNG")有什么区别:

SecureRandom

java.security 类 SecureRandom 是java中的提供加密的强随机生成器。与Java其他算法一样,SecureRandom也提供了实现无关的算法。所以,调用的时候会请求特定的RNG 算法并将它回传到该算法的SecureRandom对象中。如果需要,还可以通过特定的提供程序请求特定的算法。如:

SecureRandom random = SecureRandom.getInstance("SHA1PRNG");

系统将确定环境中是否有所请求的算法实现,是否有多个,是否有首选实现。

还有一种就我使用的:

SecureRandom 实现尝试完全随机化生成器本身的内部状态,除非调用方在调用 getInstance 方法之后又调用了 setSeed 方法:

SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
random.setSeed(seed);

这样就可以兼容不同的操作系统。

Bug年年有,今天特别多。收工