【问题标题】:RSA encryption causing IllegalBlockSizeException in JavaRSA 加密在 Java 中导致 IllegalBlockSizeException
【发布时间】:2021-04-10 07:36:15
【问题描述】:

使用以下方法生成 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。 所以我不认为这是一个编码问题,我在从一个失败的实例中对其进行加密之前打印了字符串,并在单元测试中对其进行了测试,没有任何问题通过。

【问题讨论】:

  • 这可能是您的 JCE 中的错误,但也可能是您的代码中的错误。 32 字节密钥 + 16 字节 IV 组成 48 字节。如果 base64 编码,它应该是 64 而不是 70。你能创建一个 minimal reproducible example 来证明你的问题吗?
  • 供参考,可能有用knowledgefactory.net/2020/10/…
  • 顺便说一句,当前显示的代码很好。
  • 没有理由在 加密数据之前对数据进行 base64 编码。

标签: java spring encryption public-key-encryption


【解决方案1】:
  1. 您可以使用 AES 和 AES 密钥加密文本(要传输的数据) RSA。
  2. 稍后您必须推送 RSA 加密的 AES 密钥和 AES 加密文本 到服务器。
  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);

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

直接使用 InputStream 和 OutputStream 可能会有问题。所以在传输数据(加密的 AES 密钥,文本)时使用 ObjectStreams。

【讨论】:

  • 是的,这是一项春季服务,您提到的方法是我所采用的。我有一个类似的想法,认为这是一个编码问题,所以我记录了要加密的密钥,在加密之前打印大小。它始终是 70 个字节,这就是我对错误感到困惑的原因。
  • 如何发送加密文本和aes密钥?
  • 加密后,我会在 http 响应中发送它
  • 发送到服务器时可以使用对象流。只需 sen 对象并直接获取对象
猜你喜欢
  • 2019-03-14
  • 2013-02-01
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
  • 2014-11-24
  • 2011-12-10
  • 1970-01-01
  • 2014-06-02
相关资源
最近更新 更多