java ArrayIndexOutOfBoundsException:RSA 块的数据过多
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17811009/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ArrayIndexOutOfBoundsException : too much data for RSA block
提问by Bahad?r Y?lmaz
I have some problem with my android application. I am trying to an app related with RSA encryption/decryption.this is my problem:
我的 android 应用程序有问题。我正在尝试与 RSA 加密/解密相关的应用程序。这是我的问题:
I can encrypt short sentences clearly, but when i try to decrypt this message to orginal text I give an error ("too much data for RSA block"). And also if I want to encrypt a long sentences i have same error.I had some search for this problem, and found some solution in this sites:
我可以清楚地加密短句,但是当我尝试将此消息解密为原始文本时,我给出了一个错误(“RSA 块的数据太多”)。而且,如果我想加密一个长句子,我也会遇到同样的错误。我对这个问题进行了一些搜索,并在以下站点中找到了一些解决方案:
But i dont understand anything, these solutions are so complicated.How can i fixed this problem, Can anyone give me a more simple solution? Thank you.
但是我什么都不明白,这些解决方案太复杂了。我该如何解决这个问题,谁能给我一个更简单的解决方案?谢谢你。
ED?T: These are the code blocks that i use for this project.
ED?T:这些是我用于这个项目的代码块。
public String RSAEncrypt(String plain) throws NoSuchAlgorithmException, NoSuchPaddingException,InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException, UnsupportedEncodingException {
publicKey = getPublicKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] cipherData = cipher.doFinal(plain.getBytes());
return Base64.encodeToString(cipherData, Base64.DEFAULT);
}
public String RSADecrypt(byte[] encryptedBytes) throws NoSuchAlgorithmException, NoSuchPaddingException,InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException, UnsupportedEncodingException {
privateKey = getPrivateKey();
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] cipherData = cipher.doFinal(encryptedBytes);
return Base64.encodeToString(cipherData, Base64.DEFAULT);
}
回答by erickson
RSA can only encrypt messages that are several bytes shorter than the modulus of the key pair. The extra bytes are for padding, and the exact number depends on the padding scheme you are using.
RSA 只能加密比密钥对的模数短几个字节的消息。额外的字节用于填充,确切的数字取决于您使用的填充方案。
RSA is for key transport, not data encryption. If you have a long message, encrypt it with AES, using a random key. Then encrypt the AES key with RSA, using the public key of the message recipient. You should be using the Cipher
class's wrap()
and unwrap()
methods.
RSA 用于密钥传输,而不是数据加密。如果您有一条长消息,请使用随机密钥使用 AES 对其进行加密。然后使用消息接收者的公钥用 RSA 加密 AES 密钥。您应该使用Cipher
类wrap()
和unwrap()
方法。
This is how PGP, S/MIME, TLS (roughly), and any other correctly designed RSA encryption schemes work.
这就是 PGP、S/MIME、TLS(大致)和任何其他正确设计的 RSA 加密方案的工作原理。
回答by Sira Lam
In my use case, I need to encrypt some request data to server, from my app.
在我的用例中,我需要从我的应用程序加密一些到服务器的请求数据。
If I encrypt the AES key with RSA, that's kind of meaningless because the point of using RSA instead of AES, is to prevent reverse-engineering to get the AES key (versus RSA needs a private key stored in server for decryption). Since the AES key needs to be stored in the app locally, I cannot use the approach as suggested by erickson.
如果我用 RSA 加密 AES 密钥,那是毫无意义的,因为使用 RSA 而不是 AES 的目的是防止反向工程来获取 AES 密钥(相对于 RSA 需要存储在服务器中的私钥进行解密)。由于 AES 密钥需要本地存储在应用程序中,因此我无法使用 erickson 建议的方法。
Instead, I split the long string into List<String>
(Each length suggested by server provider); and encrypt each String.
相反,我将长字符串拆分为List<String>
(服务器提供商建议的每个长度);并加密每个字符串。
After that, the List<String>
is passed to server in a json array, and let server decrypt each and re-join them.
之后,将List<String>
json 数组传递给服务器,让服务器解密每个并重新加入它们。
Of course, this approach needs your server's support, and can potentially has performance issue.
当然,这种方法需要您的服务器的支持,并且可能存在性能问题。