2014-01-25 35 views
0

我需要將一些使用Blowfish加密的數據從基於java的服務器發送到客戶端。我可以成功加密數據,但我無法在客戶端解密它。Java和Javascript Blowfish

這裏是我的Java代碼:

byte[] kd = key.getBytes("UTF-8"); 

SecretKeySpec ks = new SecretKeySpec(kd, "Blowfish"); 
Cipher cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); 
cipher.init(Cipher.ENCRYPT_MODE, ks); 

byte[] encrypted = cipher.doFinal(text.getBytes("UTF-8")); 

String str = new String(encrypted, "UTF-8"); 

至於JS庫,我決定使用this之一。

out = blowfish.decrypt(code, skey, {cipherMode: 1, outputType: 0}) 

因此,我得到了一些奇怪的字符。我的代碼有什麼問題?

UPD: 此代碼的工作完美:

byte[] kd = key.getBytes("UTF-8"); 

SecretKeySpec ks = new SecretKeySpec(kd, "Blowfish"); 
Cipher cipher = Cipher.getInstance("Blowfish"); 
cipher.init(Cipher.ENCRYPT_MODE, ks); 

byte[] encrypted = cipher.doFinal(text.getBytes("UTF-8")); 

String str = new String(Base64.encodeBase64(encrypted), "UTF-8"); 

JS:

out = blowfish.decrypt(code, skey, {cipherMode: 0, outputType: 0}) 
+1

可能是一些事情,但我的猜測會是其中的一種:1)關鍵是不同的(可能是因爲編碼?直接使用字符串作爲關鍵字有點奇怪)。 2)IV是不同的(CBC模式需要一個IV,你從來沒有直接指定過,你知道默認是什麼嗎?這兩個庫是否相同?)3)你的JS代碼沒有使用CBC模式或PKCS5填充(到底什麼是「cipherMode:1」?) – zindorsky

+0

關鍵是一樣的。也許你對編碼是正確的。 「cipherMode:1」表示CBC。但是,我不知道這個JS庫使用什麼樣的填充。 –

+2

'String str = new String(encrypted,「UTF-8」)'這不能工作。加密的輸出是任意字節,通常不是有效的UTF-8序列。在這裏使用Base64或Hex。 – CodesInChaos

回答

0

發送與它\u0000字節的文本到瀏覽器可能會導致各種奇怪的問題。這就是爲什麼你應該編碼數據BASE64,將其發送到客戶端,然後在本地進行解碼。

另一個問題是new String(encrypted, "UTF-8");,因爲編碼的字節數組將包含非法的UTF-8序列。相反,嘗試使用new String(encrypted, "iso-8859-1");,它是任意字節的1:1編碼。但是再次,0字節可能會混淆其中的某個組件。