获取错误java.lang.ArrayIndexOutOfBoundsException:RSA块的数据太多

时间:2013-04-04 08:29:45

标签: java android encryption rsa

我有私有pem密钥文件,我正在使用该文件来签名和加密数据。 签名工作正常,我也可以在另一个平台上验证,但在加密数据时,我得到以下错误:

04-04 09:55:51.821: E/AndroidRuntime(2725): FATAL EXCEPTION: Thread-102
04-04 09:55:51.821: E/AndroidRuntime(2725): java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block
04-04 09:55:51.821: E/AndroidRuntime(2725):     at com.android.org.bouncycastle.jce.provider.JCERSACipher.engineDoFinal(JCERSACipher.java:457)
04-04 09:55:51.821: E/AndroidRuntime(2725):     at javax.crypto.Cipher.doFinal(Cipher.java:1106)
04-04 09:55:51.821: E/AndroidRuntime(2725):     at com.example.testsigning.MainActivity.rsaEncrypt(MainActivity.java:185)
04-04 09:55:51.821: E/AndroidRuntime(2725):     at com.example.testsigning.MainActivity$1.run(MainActivity.java:51)
04-04 09:55:51.821: E/AndroidRuntime(2725):     at java.lang.Thread.run(Thread.java:856)

以下是从私人文件中提取密钥的代码段:

// Read the file into string
String privKeyPEM = readFile("/mnt/sdcard/rsa_key");

privKeyPEM = privKeyPEM.replace("-----BEGIN RSA PRIVATE KEY-----", "");
privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", "");

// Base64 decode the data
byte[] encoded = Base64.decode(privKeyPEM, Base64.DEFAULT);

// PKCS8 decode the encoded RSA private key
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(encoded);
KeyFactory kf = KeyFactory.getInstance("RSA");
mPrivKey = kf.generatePrivate(keySpec);

RSAPrivateCrtKey privk = (RSAPrivateCrtKey) mPrivKey;

RSAPublicKeySpec pubKeySpec = new java.security.spec.RSAPublicKeySpec(
        privk.getPublicExponent(), privk.getModulus());

mPubKey = kf.generatePublic(pubKeySpec);

以下是加密数据的代码段:

Cipher cipher = Cipher.getInstance("RSA/None/OAEPWithSHA1AndMGF1Padding", "BC");
cipher.init(Cipher.ENCRYPT_MODE, mPubKey);
return cipher.doFinal("Hello World".getBytes()); // here is the problem

我们非常感谢您解决此问题的任何帮助。

此致 Yuvi

3 个答案:

答案 0 :(得分:1)

问题在于从私钥中检索公钥,它应该是这样的:

RSAPublicKeySpec pubKeySpec = new java.security.spec.RSAPublicKeySpec(
                privk.getModulus(), privk.getPublicExponent());

而不是:

RSAPublicKeySpec pubKeySpec = new java.security.spec.RSAPublicKeySpec(
        privk.getPublicExponent(), privk.getModulus());

答案 1 :(得分:0)

当输入缓冲区大于密码的输入块大小时,会出现该错误消息。输入字符串很短的情况似乎不太可能,因此首先要看的是前一行。我认为密码没有得到正确的初始化,或者更确切地说,没有按照你期望的方式进行初始化,因为它没有抛出异常。我将首先在init()调用之后对密码对象进行一些调试打印。

答案 2 :(得分:0)

该死的我有同样的错误,但原因是我正在阅读使用StringBuilder而不是ByteArrayOutputStream解密的材料(StringBuilder的实例使用追加方法,附加行并损坏原始来源进行解密)。

:/