获取 IllegalBlockSizeException:使用 rsa 时数据不得超过 256 字节

新手上路,请多包涵

我正在使用 rsa 密钥加密我将发送到我的服务器的长字符串(将使用服务器的公钥和我的私钥对其进行加密)但是它会抛出一个异常 javax.crypto.IllegalBlockSizeException: Data must not be longer than 256 bytes 我觉得我还没有理解到目前为止,rsa 的工作正常(使用内置库是造成这种情况的原因)。

有人可以解释为什么抛出这个异常吗?发送加密的长字符串是完全不可能的吗?

原文由 Ashwin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.2k
2 个回答

RSA算法只能加密最大字节长度为RSA密钥位长度除以8减11个填充字节的数据,即最大字节数=密钥位长度/8-11。

所以基本上你将密钥长度除以 8 -11(如果你有填充)。例如,如果你有一个 2048 位的密钥,你可以加密 20488 = 256 字节(- 11 字节,如果你有填充)。因此,要么使用更大的密钥,要么使用对称密钥加密数据,然后使用 rsa 加密该密钥(这是推荐的方法)。

这将要求您:

  1. 生成对称密钥
  2. 使用对称密钥加密数据
  3. 使用 rsa 加密对称密钥
  4. 发送加密密钥和数据
  5. 使用 rsa 解密加密的对称密钥
  6. 使用对称密钥解密数据
  7. 完毕 :)

原文由 John Snow 发布,翻译遵循 CC BY-SA 3.0 许可协议

基于@John Snow 的回答,我做了一个例子

  1. 生成对称密钥(128 位 AES)
    KeyGenerator generator = KeyGenerator.getInstance("AES");
   generator.init(128); // The AES key size in number of bits
   SecretKey secKey = generator.generateKey();

  1. 使用 AES 加密纯文本
   String plainText = "Please encrypt me urgently..."
   Cipher aesCipher = Cipher.getInstance("AES");
   aesCipher.init(Cipher.ENCRYPT_MODE, secKey);
   byte[] byteCipherText = aesCipher.doFinal(plainText.getBytes());

  1. 使用 RSA 公钥加密密钥
   KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
   kpg.initialize(2048);
   KeyPair keyPair = kpg.generateKeyPair();

   PublicKey puKey = keyPair.getPublic();
   PrivateKey prKey = keyPair.getPrivate();

   Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
   cipher.init(Cipher.PUBLIC_KEY, puKey);
   byte[] encryptedKey = cipher.doFinal(secKey.getEncoded()/*Seceret Key From Step 1*/);

  1. 发送加密数据(byteCipherText)+加密的AES Key(encryptedKey)

  2. 在客户端,使用 RSA 私钥解密对称密钥

   cipher.init(Cipher.PRIVATE_KEY, prKey);
   byte[] decryptedKey = cipher.doFinal(encryptedKey);

  1. 使用解密的对称密钥解密密文
   //Convert bytes to AES SecertKey
   SecretKey originalKey = new SecretKeySpec(decryptedKey , 0, decryptedKey .length, "AES");
   Cipher aesCipher = Cipher.getInstance("AES");
   aesCipher.init(Cipher.DECRYPT_MODE, originalKey);
   byte[] bytePlainText = aesCipher.doFinal(byteCipherText);
   String plainText = new String(bytePlainText);`

原文由 Waleed Abdalmajeed 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题