JAVA下DES加解密在linux与windows下的兼容问题

蜗牛Running 2016-09-29

        前段时间做了DES加密解密,采用的是javax下的DES算法,在windows下写的倒挺快,现在部署到linux上测试的时候,组长一脸严肃的找到我,声色俱厉地问我为毛测试数据都不能解密了!你写的什么JB毛算法!马上就要测试了!你给我搞神马!

   天地良心,我测的很棒的,还拉出来那个小class放到服务器上跑了啊!扶扶眼镜,赶紧下手改,找了半天发现原因如下:

   1. windows下写的的DES算法写起来很飘逸,然而在linux这个严肃的大叔面前,一切都是浮云,生成随机数的

SecureRandom secureRandom = SecureRandom.getInstance();
 需要加个限制,改成
SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
 

        2.上面仅仅是第一步,提上去还是不行,于是我就把密钥的生成由KeyGenerator换成了SecretKeyFactory,然而一切都是浮云,linux仍然一张臭脸告诉我Given final block not properly padded。一转脸,组长的脸快拉长到东京了,赶紧继续排查

        3.第三步我想到,难道是DES补位导致的?于是把补位规则改成了"DES/ECB/PKCS5Padding",搞定了,组长啥也没说,走了。

        总结起来,DES算法对位数不足8位倍数的字符串进行加密的时候是本身是不补位的,填补方式由程序员自己定,我在windows下任性地写成了NoPadding模式,即填补方式为补充\0或者空格,然后trim;之前的测试数据是在windows下生成的,linux拿过来解密的时候一看,我擦,这是什么玩意儿,随手给扔了,报错;改成了填补方式为"DES/ECB/PKCS5Padding"也就是PKCS5Padding模式之后,windows和linux都遵循同一套填补方式,加密前对数据字节长度对8取余,余数大于0,则差几个字节就补几个字节,字节数值即为补充的字节数,若为0则补充8个字节的8 ,解密后就取最后一个字节,值为m,则从数据尾部删除m个字节,剩余数据即为加密前的原文。

        至于

SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
 为啥要加"SHA1PRNG" 的问题,因为对于直接用
SecureRandom secureRandom = SecureRandom.getInstance();
 在java文档中写的是Constructs a secure random number generator (RNG) implementing the default random number algorithm. 这样linux和windows的默认伪随机数生成算法是有区别的。linux中采用的是/dev/random生成伪随机数,当然还有/dev/urandom这个二逼低强度的副本;windows中则不然,使用的是CryptGenRandomRtlGenRandom这两个算法来生成。估计这就是为何跨平台的时候需要使用"SHA1PRNG" 强随机种子算法的原因了吧!然而即便如此,java文档中提到还有一个制定伪随机数算法提供者的玩意儿,例如写成
SecureRandom secureRandom =SecureRandom.getInstance("SHA1PRNG","SUN");
 意思是告诉系统使用SUN提供的强随机种子算法,然而SUN的实现和Apache是不同的,搞不好就乱了,所以一般不用提供provider,希望系统之间不出问题就好。

        好,还有第二步的问题,使用KeyGenerator还是SecretKeyFactory的问题。讲真,这俩在解决这次问题中基本上没起作用,但有必要讲一下。密钥的生成在ORACLE的Standard Algorithm Name Documentation 中是有说明的,先说四个吧,KeyGenerator、SecretKeyFactory、KeyFactory、KeyPairGenerator。其中KeyGenerator和SecretKeyFactory都是javax.crypto包下的,主要提供给对称和非可逆加密算法,其中KeyGenerator主要提供给非可逆算法,SecretKeyFactory主要提供给对称加密算法;KeyFactory和KeyPairGenerator是在java.security包中的,主要提供给非对称加密算法的。

       OK,搞清楚了这回

相关推荐