rsa默认最多只能加密密钥长度/8-11长度的明文,最多只能解密密钥长度/8长度的密文,如:
密钥长度为1024,则明文长度最长117,密文长度最长128。
可以采用分段加解密的方式,增加明文密文长度(同时加解密的效率也会按比例降低)。
工具类如下:
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
@Slf4j
public class RSACipher {
public static String AlgorithmName = "RSA";
public static String Algorithm = "RSA/ECB/PKCS1Padding";
public static int KeyLength = 2048;
private static int MAX_ENCRYPT_BLOCK = 117;
private static int MAX_DECRYPT_BLOCK = 128;
static {
MAX_ENCRYPT_BLOCK = KeyLength/8 - 11;
MAX_DECRYPT_BLOCK = KeyLength/8;
}
@Getter
private String publicKey;
@Getter
private String privateKey;
//公钥加密
private Cipher publicEncryptCipher = null;
//私钥解密
private Cipher privateDecryptCipher = null;
//私钥加密
private Cipher privateEncryptCipher = null;
//公钥解密
private Cipher publicDecryptCipher = null;
public RSACipher(String publicKey, String privateKey) {
this.init(publicKey, privateKey);
}
public void init(String publicKey, String privateKey){
this.publicKey = publicKey;
this.privateKey = privateKey;
//公钥加密
byte[] decoded = Base64.decodeBase64(publicKey);
RSAPublicKey pubKey = null;
try {
pubKey = (RSAPublicKey) KeyFactory.getInstance(AlgorithmName).generatePublic(new X509EncodedKeySpec(decoded));
// publicCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
publicEncryptCipher = Cipher.getInstance(Algorithm);
publicEncryptCipher.init(Cipher.ENCRYPT_MODE, pubKey);
} catch (InvalidKeySpecException | InvalidKeyException |
NoSuchPaddingException | NoSuchAlgorithmException e) {
log.warn(ExceptionHelper.getStackTraceString(e));
}
//私钥解密
//64位解码加密后的字符串
//base64编码的私钥
byte[] decoded2 = Base64.decodeBase64(privateKey);
RSAPrivateKey priKey = null;
try {
priKey = (RSAPrivateKey) KeyFactory.getInstance(AlgorithmName).generatePrivate(new PKCS8EncodedKeySpec(decoded2));
// privateCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
privateDecryptCipher = Cipher.getInstance(Algorithm);
privateDecryptCipher.init(Cipher.DECRYPT_MODE, priKey);
} catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException |
InvalidKeyException e) {
log.warn(ExceptionHelper.getStackTraceString(e));
}
//私钥加密
byte[] decoded3 = Base64.decodeBase64(privateKey);
RSAPrivateKey pubKey2 = null;
try {
pubKey2 = (RSAPrivateKey) KeyFactory.getInstance(AlgorithmName).generatePrivate(new PKCS8EncodedKeySpec(decoded3));
// publicCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
privateEncryptCipher = Cipher.getInstance(Algorithm);
privateEncryptCipher.init(Cipher.ENCRYPT_MODE, pubKey2);
} catch (InvalidKeySpecException | InvalidKeyException |
NoSuchPaddingException | NoSuchAlgorithmException e) {
log.warn(ExceptionHelper.getStackTraceString(e));
}
//公钥解密
//64位解码加密后的字符串
//base64编码的私钥
byte[] decoded23 = Base64.decodeBase64(publicKey);
RSAPublicKey priKey2 = null;
try {
priKey2 = (RSAPublicKey) KeyFactory.getInstance(AlgorithmName).generatePublic(new X509EncodedKeySpec(decoded23));
// privateCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-1AndMGF1Padding");
publicDecryptCipher = Cipher.getInstance(Algorithm);
publicDecryptCipher.init(Cipher.DECRYPT_MODE, priKey2);
} catch (InvalidKeySpecException | NoSuchAlgorithmException | NoSuchPaddingException |
InvalidKeyException e) {
log.warn(ExceptionHelper.getStackTraceString(e));
}
}
//随机生成密钥对
public static String[] genKeyPair() {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = null;
try {
keyPairGen = KeyPairGenerator.getInstance(AlgorithmName);
} catch (NoSuchAlgorithmException e) {
log.warn(ExceptionHelper.getStackTraceString(e));
}
// 初始化密钥对生成器,密钥大小为96-1024位
assert keyPairGen != null;
keyPairGen.initialize(KeyLength, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); // 得到私钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 得到公钥
String publicKeyString = new String(Base64.encodeBase64(publicKey.getEncoded()));
String privateKeyString = new String(Base64.encodeBase64((privateKey.getEncoded())));
log.info("随机生成的公钥为:" + publicKeyString);
log.info("随机生成的私钥为:" + privateKeyString);
return new String[]{publicKeyString, privateKeyString};
}
private byte[] crypt(byte[] data, Cipher cipher, int maxLength) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
int inputLen = data.length;
int offSet = 0;
byte[] cache;
// 对数据分段解密
try {
while (inputLen - offSet > 0) {
if (inputLen - offSet > maxLength) {
cache = cipher.doFinal(data, offSet, maxLength);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
offSet += maxLength;
}
return out.toByteArray();
} catch (BadPaddingException | IllegalBlockSizeException e) {
log.warn(ExceptionHelper.getStackTraceString(e));
}
finally {
try{
out.close();
}catch (Exception e){
log.warn(ExceptionHelper.getStackTraceString(e));
}
}
return null;
}
/**
* RSA分段加密
*
* @param str 加密字符串
* @return 密文
*/
private String encrypt(String str, Cipher cipher) {
//只能处理MAX_ENCRYPT_BLOCK长度的数据,故用下面的代码改写
// try {
// return Base64.encodeBase64String(cipher.doFinal(str.getBytes(StandardCharsets.UTF_8)));
// } catch (IllegalBlockSizeException e) {
// e.printStackTrace();
// } catch (BadPaddingException e) {
// e.printStackTrace();
// }
byte[] data = str.getBytes(StandardCharsets.UTF_8);
return Base64.encodeBase64String(crypt(data, cipher, MAX_ENCRYPT_BLOCK));
}
/**
* RSA分段解密
*
* @param str 加密字符串
* @return 明文
*/
private String decrypt(String str, Cipher cipher) {
//只能处理MAX_DECRYPT_BLOCK长度的数据,故用下面的代码改写
// byte[] data = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
// try {
// return new String(privateDecryptCipher.doFinal(data));
// } catch (BadPaddingException |
// IllegalBlockSizeException e) {
// e.printStackTrace();
// }
byte[] data = Base64.decodeBase64(str.getBytes(StandardCharsets.UTF_8));
byte[] result = crypt(data, cipher, MAX_DECRYPT_BLOCK);
if(result == null){
return null;
}
return new String(result, StandardCharsets.UTF_8);
}
/**
* RSA公钥加密
*
* @param str 加密字符串
* @return 密文
*/
public String publicEncrypt(String str) {
return encrypt(str, publicEncryptCipher);
}
/**
* RSA私钥解密
*
* @param str 加密字符串
* @return 明文
*/
public String privateDecrypt(String str) {
return decrypt(str, privateDecryptCipher);
}
/**
* RSA私钥加密
*
* @param str 加密字符串
* @return 密文
*/
public String privateEncrypt(String str) {
return encrypt(str, privateEncryptCipher);
}
/**
* RSA公钥解密
*
* @param str 加密字符串
* @return 明文
*/
public String publicDecrypt(String str) {
return decrypt(str, publicDecryptCipher);
}
}

浙公网安备 33010602011771号