我正在使用服务器上的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);
答案 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
调用中,始终进行单部分加密/解密。 (我想也许可以通过使用多部分加密/解密来并行加密/解密,但我从来没有足够的贪婪来惩罚试图实现这一点。)