RSA加密解密
非对称加密是一种广泛使用的数据加密算法,它使用不同的密钥进行加密和解密。RSA加密算法就是一种广泛使用的非对称加密算法。在RSA加密算法中,密钥分为公钥(可公开)和私钥(不公开)。公钥和私钥是成对出现的。 用公钥加密的数据,只有对应的私钥可以解密。 用私钥加密的数据,只有对应的公钥可以解密。
需要注意的是,RSA对加密解密长度是有限制的,加密长度不超过117Byte,所以需要通过分段来进行加密解密。
生成密钥对:
一般来说,RSA密钥的位数越大,密钥越安全,但加密和解密的速度也会变慢。常见的 RSA 密钥位数除了 1024 和 2048,还有 3072、4096 等,也有少数人使用更高的密钥位数。不过,一般来说,使用 2048 位 RSA 密钥就足够安全了。
生成的密钥对记得保存哦!!!
/***
* 生成密钥对
* @param keySize 密钥位数
* @ver v1.0.0
*/
public static void generateKeyPair(int keySize){
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(keySize);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
System.out.println("=========PublicKey Begin==========");
System.out.println(Base64.encodeBase64String(publicKey.getEncoded()));
System.out.println();
PrivateKey privateKey = keyPair.getPrivate();
System.out.println("=========PrivateKey Begin==========");
System.out.println(Base64.encodeBase64String(privateKey.getEncoded()));
} catch (NoSuchAlgorithmException e) {
log.error("RSA generator key Pair Error:{}", e.getMessage());
}
}
默认密钥位数为2048(keySize = 2048)
private static final String ALGORITHM = "RSA";
private static final int KEY_SIZE = 2048;
private static final Integer MAX_ENCRYPT_LENGTH = 117;
private static final String PUBLIC_KEY = "";
private static final String PRIVATE_KEY = "";
分段加密:
/**
* 公钥 分段加密--默认密钥位数为2048
* @param plaintext 明文
* @return {@link String}
* @ver v1.0.0
*/
public static String encryptSection(String plaintext) {
if(StringUtils.isEmpty(plaintext)){
log.warn("加密-->原数据为空!!!");
return null;
}
try {
//base64编码的公钥
byte[] decoded = Base64.decodeBase64(PUBLIC_KEY);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance(ALGORITHM).generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] bytes = plaintext.getBytes();
int inputLen = bytes.length;
//偏移量
int offLen = 0;
int i = 0;
ByteArrayOutputStream bops = new ByteArrayOutputStream();
while(inputLen - offLen > 0){
int length = Math.min(inputLen - offLen, MAX_ENCRYPT_LENGTH);
byte [] cache = cipher.doFinal(bytes, offLen, length);
bops.write(cache);
i++;
offLen = MAX_ENCRYPT_LENGTH * i;
}
bops.close();
return Base64.encodeBase64String(bops.toByteArray());
} catch (Exception e) {
log.error("加密失败:{}",e.getMessage());
return null;
}
}
分段解密:
/**
* 私钥 分段解密--默认密钥位数为2048
* @param ciphertext 密文
* @return {@link String}
* @ver v1.0.0
*/
public static String decryptSection(String ciphertext) {
if(StringUtils.isEmpty(ciphertext)){
log.warn("解密-->原数据为空!!!");
return null;
}
try {
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(PRIVATE_KEY);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, priKey);
//64位解码加密后的字符串
byte[] bytes = Base64.decodeBase64(ciphertext.getBytes(StandardCharsets.UTF_8));
int inputLen = bytes.length;
int offLen = 0;
int i = 0;
// 解密长度
int maxDecryptLen = KEY_SIZE / 8;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
while(inputLen - offLen > 0){
byte[] cache;
int length = Math.min(inputLen - offLen, maxDecryptLen);
cache = cipher.doFinal(bytes,offLen,length);
byteArrayOutputStream.write(cache);
i++;
offLen = maxDecryptLen * i;
}
byteArrayOutputStream.close();
return byteArrayOutputStream.toString();
} catch (Exception e) {
log.error("解密失败:{}",e.getMessage());
return null;
}
}
测试一下:
先测试一下小于117的==>
加密:
解密:
再测试一下大于117的==>
加密:
解密: