首页 > 解决方案 > RSA 加密在 Java 中导致 IllegalBlockSizeException

问题描述

使用以下命令生成 AES 密钥后:

keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256);
keyGenerator.generateKey();

我将这个密钥与一个 16 字节的 IV 连接起来,然后编码

public String encode(byte[] content) {
    return Base64.encodeBase64String(content);
 }

我将此字符串传递给 RSA 密码,如下所示

private final Cipher publicKeyCipher = Cipher.getInstance("RSA");
publicKeyCipher.init(Cipher.ENCRYPT_MODE, publicKey);
publicKeyCipher.doFinal(content.getBytes(StandardCharsets.UTF_8));

所有这些都按预期工作,测试工作正常。但是当在受控环境中进行负载测试时,doFinal 函数会抛出

{"log":"javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes\n"}

这发生在 500,000 个请求的 0-15% 左右。日志显示字符串长度和字节大小始终固定为 70,意思是低于 245。所以我认为这不是编码问题,我在从其中一个失败的实例中对其进行加密之前打印了字符串,并在通过了的单元测试中对其进行了测试没有问题。

标签: javaspringencryptionpublic-key-encryption

解决方案


  1. 您可以使用 AES 加密文本(要传输的数据),使用 RSA 加密 AES 密钥。
  2. 稍后您必须将 RSA 加密的 AES 密钥和 AES 加密的文本推送到 SERVER。
  3. 您还需要通过 RSA private.key 解密 AES 密钥并使用该 AES 密钥打开由 AES 算法加密的文本。

这是伪代码示例。

    # 客户端
    AESKey 生成AESKey = generateAESKey();
    byte[] encryptedText= generatedAESKey.encrypt("Some Text".getBytes())
    RsaEncrypted encryptedAES = RSA.encrypt(generatedAESKey); // 通过 publickey.pem
    connection.sendServer(加密AES,加密文本)
    
    # 服务器大小
    EncryptedKeyAndData encryptedKeyAndData = connection.receive();
    AESKey aesKey = RSA.decrypt(encryptedKeyAndData.encryptedAES); // 通过 privatekey.pem
    字符串文本 = aesKey.decrypt(encryptedKeyAndData.encryptedText);

我最近刚刚完成了这个实现的套接字编程使用,但我想这是一个与弹簧相关的项目。您不必实现原始客户端和服务器代码。主要问题可能是编码。

直接使用 InputStream 和 OutputStream 可能会出现问题。因此,在传输数据(加密的 AES 密钥、文本)时使用 ObjectStreams。


推荐阅读