Java RSA加密

10

我正在尝试对简单字符串 "test" 进行前后编码。

public static String encode(Key publicKey, String data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

    byte[] byteData = data.getBytes(); // convert string to byte array

    Cipher cipher = Cipher.getInstance(ALGORITHM); // create conversion processing object
    cipher.init(Cipher.ENCRYPT_MODE, publicKey); // initialize object's mode and key

    byte[] encryptedByteData = cipher.doFinal(byteData); // use object for encryption

    return new String(encryptedByteData); // convert encrypted byte array to string and return it

}

public static String decode(Key privateKey, String data) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

    byte[] byteData = data.getBytes(); // convert string to byte array

    Cipher cipher = Cipher.getInstance(ALGORITHM); // create conversion processing object
    cipher.init(Cipher.DECRYPT_MODE, privateKey); // initialize object's mode and key

    System.out.println(byteData.length);

    byte[] decryptedByteData = cipher.doFinal(byteData); // use object for decryption

    return new String(decryptedByteData); // convert decrypted byte array to string and return it

}

然而,尽管加密工作正常(算法为“RSA”),但当我尝试解密刚刚从“test”加密得到的字符串时,我遇到了以下异常:

javax.crypto.IllegalBlockSizeException:数据长度不能超过256个字节

我应该将加密后的字节分割成256字节的块,以便能够解密吗?

3个回答

9
您无法可靠地将随机字节转换为String。结果将取决于您运行此程序的计算机上的默认字符编码。对于许多编码,密文将被破坏,信息将丢失。
修改您的代码,使用byte[]代替(即“doFinal()`方法的结果)。
如果您需要将byte[]转换为字符字符串,请使用Base-64等编码方式。

啊,太好了,谢谢,完美运行!是的,我猜测问题出在将加密的字节数组转换为字符串时可能发生了损坏。 - arik

4
这里得知:
RSA算法只能加密最大字节数为RSA密钥长度(以位数表示)除以8减去11个填充字节的数据,即最大字节数=密钥长度(以位数表示)/ 8-11。如果要加密较大的数据,则使用更大的密钥,例如具有4096位的密钥将允许您加密501个字节的数据。

1
尽管我已经以与Google搜索结果完全相同的措辞阅读了该句话,但将密钥设置得更高并没有起作用。我测试了加密的字节数组长度,并注意到当将密钥长度从2048提高到4096时,字节数组长度也随之增加,在两种情况下都不适合,我都收到了异常。 - arik

4
如果您有大量数据,应该将其拆分为适合的数据块,并加密/解密每个数据块(不是很好的想法),或者使用对称算法(AES / DES / RC4等)加密/解密它们,使用RSA公钥加密对称密钥并将两者发送到另一端(更好的想法)。
第二种方法是非常常见的方法,因为非对称加密算法比对称加密算法(无论是加密还是解密)都要昂贵得多。

谢谢。当数据实际超过限制时,我会这样做,但在加密像“test”这样简单的字符串时,问题并不在于此。 - arik
是的,我误读了你的问题,但我认为这仍然是一个对未来有益的好建议。祝你好运! - MByD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接