我正在使用RSA加密文本和解密文本.使用openssl工具生成公钥和私钥.我在解密数据时遇到"java.lang.ArrayIndexOutOfBoundsException:RSA block的数据太多"异常.
这是RSA util类:
package studio.uphie.app;
import android.util.Base64;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;
/**
* Created by Uphie on 2016/4/11.
*/
public class RSA {
private static String RSA = "RSA";
/**
*
* @param text text to be encrypted
* @param pub_key rsa public key
* @return encrypted data in byte-array form
*/
public static byte[] encryptData(String text, String pub_key) {
try {
byte[] data = text.getBytes();
PublicKey publicKey = getPublicKey(Base64.decode(pub_key.getBytes(), Base64.DEFAULT));
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
*
* @param text text to be decrypted
* @param pri_key rsa private key
* @return
*/
public static byte[] decryptData(String text, String pri_key) {
try {
byte[] data = text.getBytes();
PrivateKey privateKey = getPrivateKey(Base64.decode(pri_key.getBytes(),Base64.DEFAULT));
Cipher cipher = Cipher.getInstance(RSA);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
} catch (Exception e) {
//"java.lang.ArrayIndexOutOfBoundsException: too much data for RSA block" exception occurs here.
return null;
}
}
/**
*
* @param keyBytes
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public static PublicKey getPublicKey(byte[] keyBytes) throws NoSuchAlgorithmException, InvalidKeySpecException {
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
return keyFactory.generatePublic(keySpec);
}
/**
*
* @param keyBytes
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
*/
public static PrivateKey getPrivateKey(byte[] keyBytes) throws NoSuchAlgorithmException,
InvalidKeySpecException {
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(RSA);
return keyFactory.generatePrivate(keySpec);
}
}
Run Code Online (Sandbox Code Playgroud)
以及加密和解密数据的代码段:
//encrypt
byte[] e = RSA.encryptData(text, PUBLIC_KEY);
String result = Base64.encodeToString(e, Base64.DEFAULT);
tv_encrypted.setText(result);
//decrypt
byte[] d = RSA.decryptData(text, PRIVATE_KEY);
String result = Base64.encodeToString(d, Base64.DEFAULT);
tv_decrypted.setText("Decrypted result?\n" + result);
Run Code Online (Sandbox Code Playgroud)
我知道原因可能是要解密的文本太长,但我只是加密"abc"然后解密加密的"abc".如果要加密或解密的文本应该比rsa私钥少11个字节,如何处理加密长文本?我该怎么做才能解决它?我是RSA的新手.
提前致谢!
您缺少代码中的某些步骤,因此无法检查.但是,有一些线索表明存在问题.您的decryptData方法接受String参数,然后调用String.getBytes()以获取然后解密的数据.但是,加密的结果是一个字节序列,它不是任何有效字符串的编码.也许你的意思是base64解码输入而不是调用getBytes().通常,要执行解密和解码,必须反转在加密和编码期间执行的步骤.所以,如果明文是一个byte [],那么步骤是:
byte []→加密→byte []→Base64编码→字符串.
然后,在解密方向上,您以Base64字符串开头,您必须按顺序:
字符串→Base64解码→byte []→解密→byte []
此外,另一个不良做法的问题和许多可移植性错误的来源是使用默认值.你在两个地方使用默认值,它们都很麻烦.首先,您使用的是默认的no-args String.getBytes()方法,并且可能与one-arg String (byte [])构造函数匹配.这使用平台默认字符集,但这在不同平台上可能有所不同.因此,请始终指定字符集.对于大多数应用来说,'UTF-8'是理想的选择.其次,您在Cipher.getInstance('RSA')不指定填充的情况下进行调用.Oracle的Java和Android的Java将为您提供不同的填充,因此您的代码将无法在平台之间移植.始终指定完整的填充字符串.如果您需要可移植到较旧的Java实现,那么选择就更难了.OAEP填充应该是您的首选,因此Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");可能是正确的选择.有关进一步讨论,请参阅此
| 归档时间: |
|
| 查看次数: |
5107 次 |
| 最近记录: |