最近工作中遇到了AES加解密数据的需求,在单元测试用Java实现的AES加解密工具类的时发现一个有趣的问题,加解密代码在Windows系统上可以正常运行,但是在Linux系统上,加解密时突然报了javax.crypto.BadPaddingException: Given final block not properly padded
。下面来尝试探讨和解决下这个问题。
##问题代码
异常的实际原因是SecureRandom
初始化方式问题。
##原因分析SecureRandom
实现完全随操作系统本身的內部状态,除非调用方在调用getInstance
方法之后又调用了setSeed
方法;该实现在windows上每次生成的key都相同,但是在 solaris或部分linux系统上则不同。
##解决方案
根据上述原因分析,我们需要对SecureRandom
的初始化做一些调整,首先调用getInstance
方法初始化之后,再调用setSeed
方法设置随机种子,这样就可以忽略操作系统的区别。所以还是说,Java所谓的操作系统无关性还是有点坑啊。
##结论
虽然改进后的代码完美解决了Linux系统AES加解密的坑,但是我Google了很久也没搞清楚原因是什么,希望懂的同学可以帮忙解惑。然后也查到一些资料说,如果将随机种子设置的话,随机种子就固定了,可能会有一些安全问题,所以这种方式可能还不是最好的方案,如果对安全性要求较高,建议使用AES CBC的方案。
参考资料