1. 程式人生 > >JAVA下DES加解密在linux與windows下的相容問題(從ITEYE搬家過來的)

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模式,即填補方式為

補充\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,搞清楚了這回