JAVA下DES加解密在linux與windows下的相容問題(從ITEYE搬家過來的)
前段時間做了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模式,即填補方式為
至於
為啥要加"SHA1PRNG" 的問題,因為對於直接用SecureRandom secureRandom = SecureRandom.getInstance("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中則不然,使用的是CryptGenRandom和RtlGenRandom這兩個演算法來生成。估計這就是為何跨平臺的時候需要使用"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,搞清楚了這回