2011-05-27 127 views
2

在Java中使用RSA加密/解密時,我遇到了一個非常奇怪的問題。有效數據填充數據的RSA解密失敗(BadPaddingException)

示例代碼:

KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); 
kpg.initialize(2048); 
KeyPair kp = kpg.genKeyPair(); 

Cipher enc = Cipher.getInstance("RSA"); 
enc.init(Cipher.ENCRYPT_MODE, kp.getPublic()); 
String CipherText = new String(enc.doFinal(PlainText.getBytes())); 
System.out.println("CipherText: ") + CipherText); 

Cipher dec = Cipher.getInstance("RSA"); 
dec.init(Cipher.DECRYPT_MODE, kp.getPrivate()); 
PlainText = new String(dec.doFinal(CipherText.getBytes())); 
System.out.println("PlainText: " + PlainText); 

大家都可以清楚地看到:我使用加密的公鑰,然後我用私鑰解密密文的明文。

此代碼崩潰,並顯示以下消息:

Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero 

我也試圖明確地使用「RSA/ECB/NoPadding」和失敗上解碼週期。 (例如,解碼的密文與原始明文不匹配)。

最後但並非最不重要的,我曾嘗試用自己的PKCS1.5填充功能阿拉PKCS1.5規範何時執行此:

EMB = 00 || 02 || RD || 00 || MD
EMB被編碼長度爲k
的messageblock其中RD是8個隨機非零字節
MD是最大長度爲k = 11,並且任選地與零個字節填充到使EMB長度爲k。

經過兩天的測試,我只能斷定Java中的RSA算法存在缺陷或者根本沒有執行我期望的性能。

對上述代碼的任何建議或修復都非常受歡迎,因爲我完全難以理解爲什麼上面的代碼不會按預期工作。

回答

2

不要這樣做:

String CipherText = new String(enc.doFinal(PlainText.getBytes())); 

兩個原因:

  • 這幾乎從未一個好主意,打電話String.getBytes()沒有指定的編碼。你真的希望結果取決於系統默認編碼嗎?
  • 將二進制加密操作的結果(即不透明二進制數據)作爲編碼字符串處理絕對不是一個好主意。使用Base64或十六進制進行編碼。

您可以使用Apache Commons Codec執行base64編碼/解碼操作或this standalone public domain encoder/decoder

+0

非常感謝Jon。經過另一次測試,我忽略了字符串轉換,之後它正常運行。它還早*嘆氣* – djBo 2011-05-27 09:22:57