2013-01-08 20 views
0

我加密/解密如下消息: 加密字符串 - > base64編碼字節 - >序列化字符串 - >反序列化字符串 - >解碼b64 - >解密字節。使用RSA的解密結果在普通Java和Android中有所不同

加密看起來是這樣的:

PublicKey pubKey = readPublicKey(); 
Cipher cipher; 
cipher = Cipher.getInstance(CRYPTO_ALG); 
cipher.init(Cipher.ENCRYPT_MODE, pubKey); 
byte[] cipherData; 
cipherData = cipher.doFinal(message.getBytes()); 
return cipherData; 

解密完成,像這樣:

PrivateKey pk = readPrivateKey(); 
Cipher cipher = Cipher.getInstance(CRYPTO_ALG); 
cipher.init(Cipher.DECRYPT_MODE, pk); 

return new String(cipher.doFinal(data)); 

鍵是這樣寫的:

ObjectInputStream oin = 
    new ObjectInputStream(new BufferedInputStream(is)); 
BigInteger m = (BigInteger) oin.readObject(); 
BigInteger e = (BigInteger) oin.readObject(); 

RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e); 
KeyFactory fact = KeyFactory.getInstance("RSA"); 
PrivateKey privKey = fact.generatePrivate(keySpec); 

return privKey; 

我省略了B64的東西在這裏,但我已經證實,問題不會影響該代碼。

現在發生的事情是,我實際上得到了正確的答案,但它前面加了二進制亂碼。如果我加密「TESTDATA」,我會得到TESTDATA。該代碼在普通Java中運行正常,但在Android中失敗。有誰知道如何解決這一問題?

編輯:使用RSA/NONE/NoPadding加密/解密似乎沒有幫助。我也在普通的JRE中使用org.bouncycastle。

+0

這可以幫助嗎? http://stackoverflow.com/questions/10306560/android-jvm-difference-in-rsa-decryption –

+0

http://stackoverflow.com/questions/7787328/rsa-encrypt-and-crypt-strings-on-android –

+0

@Milos:這似乎很合理,但是當我使用「RSA/NONE/NoPadding」進行加密/解密時,它不起作用。輸出結果都是亂碼。我錯過了什麼嗎?產生密鑰時,我是否必須改變某些內容? – navlelo

回答

1

根據我的經驗,默認值是Java加密中難以發現的錯誤的巨大且永無止境的來源。他們可以咬任何人,但他們捕食初學者。初學者最有可能選擇違約,因爲就其性質而言,他們感到困惑並期待簡化。它們很難被發現,幾乎看不見,因爲它們在那裏不是而是。當你看着String.getBytes()它看起來完全無辜。爲什麼初學者懷疑new String(s.getBytes())有沒有而不是等於s?最糟糕的是,測試似乎表明它是真實的。只有當您將byte[]s.getBytes()傳輸到具有不同平臺默認字符集的其他平臺時,您纔會發現該錯誤。

永不使用String.getBytes(),總是使用String.getBytes(Charset)。永遠不要使用構造函數String(byte[]),總是使用String(byte [], Charset)構造函數。您始終可以使用UTF-8字符集(Charset.forName("UTF-8"))。我專門使用它。

同樣,在Cipher.getInstance(String)工廠方法中始終指定所有三個組件算法/模式/填充