簡體   English   中英

使用RSA的解密結果在普通Java和Android中有所不同

[英]Decryption result using RSA differs in plain Java and Android

我對消息進行加密/解密,如下所示:加密字符串-> base64編碼字節->序列化字符串->反序列化字符串->解碼b64->解密字節。

加密如下所示:

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。

以我的經驗,默認值是Java加密中難以發現的錯誤的巨大且永無止境的來源。 他們可以咬任何人,但它們會捕食初學者。 初學者最有可能選擇默認值,因為就其本質而言,它們很困惑並且正在尋求簡化。 而且很難發現它們,甚至幾乎看不見,因為它們存在。 當您查看String.getBytes()它看起來完全是無辜的。 為什么初學者會懷疑new String(s.getBytes())永遠等於s 最糟糕的是,測試似乎表明它是真實的。 僅當您將s.getBytes() byte[]s.getBytes()傳輸到具有不同平台默認字符集的另一個平台時,您才注意到該錯誤。

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM