2013-04-28 124 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