java - 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。所以我认为这不是编码问题,我在从其中一个失败的实例中对其进行加密之前打印了字符串,并在通过了的单元测试中对其进行了测试没有问题。
解决方案
- 您可以使用 AES 加密文本(要传输的数据),使用 RSA 加密 AES 密钥。
- 稍后您必须将 RSA 加密的 AES 密钥和 AES 加密的文本推送到 SERVER。
- 您还需要通过 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。
推荐阅读
- javascript - Microsoft Graph api - 将文件写入我的 oneDrive
- python - 每当我运行需要 aiohttp 库的代码时出错
- amazon-web-services - 如何将 dynamodb 中新添加的数据传输到 s3 存储桶?
- apache - 当我更改源文件时,为什么我的 localhost 不再更新?
- vba - 循环查找文件夹中具有特定名称的最后修改文件
- python-3.x - TypeError: '<=' 在 'str' 和 'int' 的实例之间不支持,尽管我将 str 转换为 int
- model - 如何在 libgdx 中首先缩放然后旋转模型实例
- flutter - Flutter - 每次我重新打开小部件时,TextField 都是空的
- python - 从数据框中选择行,其中列值是字符串列表
- python - 使用 f.readline() 读取特定行 - Discord.py