2013-04-28 121 views
0

我的服務器Java的多RSA解密

$rsa->loadKey($encryptkey); 
$rsa->setEncryptionMode(CRYPT_RSA_ENCRYPTION_PKCS1); 
$ciphertext = $rsa->encrypt($str); 

上加密與phpseclib數據和我的Java應用程序接收它。數據是384字節(3 * 128)。

在Java中,我試圖解密(它們密鑰已被適當地分配),但我得到這個異常:

javax.crypto.IllegalBlockSizeException: Data must not be longer than 128 bytes 

下面是我一起工作的代碼。我有data =的2行,因爲我很困惑這種情況是否屬於多級解密,因此使用更新。如果是這樣,我不明白如何使用更新和doFinal來獲取解密的數據(我的谷歌技能沒有在這裏削減)。

Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); 
cipher.init(Cipher.DECRYPT_MODE, pr); 
data = cipher.update(encrypted_data); 
data = cipher.doFinal(); 
System.out.println(data); 

回答

2

對於CRYPT_RSA_ENCRYPTION_PKCS1 phpseclib將明文分解爲適當大小的塊,並分別對每個塊進行RSA加密(請參見從#2548 here行開始的代碼)。 Java拒絕這樣做 - 這在我看來是正確的行爲 - 並且只是拋出異常。

您必須在Java代碼中自己模擬phpseclib的行爲。通過先計算的長度在RSA模量的字節,由例如以下這樣做:

int lenBytes = (((RSAKey)pr).getModulus().bitLength() + 7)/8; 

然後打破你的加密數據變成lenBytes塊。分別解密每個塊。每次解密的結果將是至多lenBytes - 11字節長的明文。將所有明文連接在一起,或許使用類似ByteArrayOutputStream的東西。

0

取出update線,並更改doFinal調用doFinal(encrypted_data) - 剛剛解密這是一個單部分操作

做多部分加密的唯一原因/解密,如果數據ISN」 (例如,如果您的加密數據位於3個不同的128位byte[]中,或者您正在使用IOstream) - 否則,通過將整個byte[]放入doFinal調用中,始終執行單部分加密/解密操作。 (我想也可能通過使用多部分加密/解密來並行加密/解密,但我從來沒有足夠的貪婪來懲罰,試圖實現這一點。)

+0

謝謝你的時間。你提到的方法是我最初嘗試這樣做,但我得到了與我在問題中描述的相同的例外。你知道那可能是什麼嗎? – DrYap 2013-04-28 21:53:48

+1

你使用什麼尺碼的鑰匙?如果您使用填充,RSA只能加密/解密與您的密鑰大小相等的字節數/ 8,-11。如果你使用一個4096位的密鑰,那麼這個應該可以做到。或者,使用AES加密您的數據,並使用RSA加密AES密鑰。 – 2013-04-28 22:01:30

+0

如果你拿走了填充,那麼你應該可以做一個3072位密鑰 - 如果你的數據是128的精確倍數,那麼你不應該需要填充 – 2013-04-28 22:09:03