0

我在服务器上使用 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);
4

2 回答 2

2

对于CRYPT_RSA_ENCRYPTION_PKCS1phpseclib,将明文分解为适当大小的块,并分别对每个块进行 RSA 加密(请参见此处从第 2548 行开始的代码)。Java 拒绝这样做——在我看来这是正确的行为——并且只是抛出一个异常。

您必须自己在 Java 代码中模拟 phpseclib 的行为。为此,您首先计算 RSA 模数的字节长度,例如:

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

然后将您的加密数据分成lenBytes块。分别解密每个块。每次解密的结果将是最多lenBytes - 11字节长的明文。将所有明文连接在一起,可能使用类似ByteArrayOutputStream.

于 2013-04-28T22:33:21.007 回答
0

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

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

于 2013-04-28T21:34:20.010 回答