Java多部分RSA解密

时间:2013-04-28 21:01:50

标签: java rsa phpseclib

我正在使用服务器上的phpseclib加密数据

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

并在我的Java应用程序中接收它。数据为384字节(3 * 128)。

在Java中我试图解密它(它们的密钥已经正确分发)但我得到了这个例外:

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

以下是我正在使用的代码。我有2行与data =,因为我很困惑这种情况是否算作多级解密,因此使用更新。如果是这样,我不明白如何使用update和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 个答案:

答案 0 :(得分: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的内容。

答案 1 :(得分:0)

删除update行,并将doFinal调用更改为doFinal(encrypted_data) - 只需将其解密为单部分操作

进行多部分加密/解密的唯一原因是数据在内存中是不连续的(例如,如果您的加密数据位于3个不同的128位byte[]中,或者您正在使用一个IOstream) - 否则,通过将整个byte[]置于doFinal调用中,始终进行单部分加密/解密。 (我想也许可以通过使用多部分加密/解密来并行加密/解密,但我从来没有足够的贪婪来惩罚试图实现这一点。)