RSA加解密工具类,可直接使用
package com.hmy.azure.common.util;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Base64Utils;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
public class RSAUtil {
private static final String ALGORITHM = "RSA";
//加密或解密长度过长会报错, 提示"最大长度不超过xxx", 所以需要分段加解密
private static final int MAX_ENCRYPT_BLOCK = 117;//Cipher一次加密最大字节长度
private static final int MAX_DECRYPT_BLOCK = 128;//Cipher一次解密最大字节长度
public static final String KEY_TYPE_PRIVATE = "private";
public static final String KEY_TYPE_PUBLIC = "public";
private RSAUtil(){}
/**
* 随机生成 KeyPair
* @return
* @throws NoSuchAlgorithmException
*/
public static KeyPair genKeyPair() throws NoSuchAlgorithmException {
//根据RSA算法获取KeyPairGenerator, 并初始化
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
keyPairGenerator.initialize(1024,new SecureRandom());
//生成KeyPair,keyPair中存储了一对秘钥
//通过KeyPair获取公钥和秘钥之后结合具体业务进行操作,比如将秘钥存入数据库等。。
//可以参考main方法中的示例将秘钥转换为字符串
return keyPairGenerator.generateKeyPair();
}
/**
* 默认公钥加密
* @param str
* @param keyStr
* @return
* @throws Exception
*/
public static String encrypt(String str, String keyStr) throws Exception{
return encrypt(str,keyStr,KEY_TYPE_PUBLIC);
}
/**
* 默认私钥解密
* @param str
* @param keyStr
* @return
* @throws Exception
*/
public static String decrypt(String str, String keyStr) throws Exception{
return decrypt(str,keyStr,KEY_TYPE_PRIVATE);
}
/**
* 加密
* @param str
* @param keyStr
* @return
* @throws Exception
*/
public static String encrypt(String str, String keyStr, String keyType) throws Exception {
//初始化加密Cipher
Cipher cipher = getCipher(str,keyStr,keyType,Cipher.ENCRYPT_MODE);
byte[] strByte = str.getBytes(StandardCharsets.UTF_8);
//分段加密
byte[] resultByte = segment(cipher,strByte,MAX_ENCRYPT_BLOCK);
return Base64Utils.encodeToString(resultByte);
}
/**
* 解密
* @param str
* @param keyStr
* @return
* @throws Exception
*/
public static String decrypt(String str, String keyStr, String keyType) throws Exception{
//初始化解密Cipher
Cipher cipher = getCipher(str,keyStr,keyType,Cipher.DECRYPT_MODE);
byte[] strByte = Base64Utils.decodeFromString(str);
//分段解密
byte[] resultByte = segment(cipher,strByte,MAX_DECRYPT_BLOCK);
return StringUtils.toEncodedString(resultByte,StandardCharsets.UTF_8);
}
/**
* 获取cipher
* @param str: 需要加解密的字符串
* @param keyStr: 密钥字符串
* @param keyType: 密钥类型
* @param cipherMode: 加解密类型
* @return
* @throws Exception
*/
private static Cipher getCipher(String str,String keyStr, String keyType, int cipherMode) throws Exception{
byte[] keyByte = Base64Utils.decodeFromString(keyStr);
Key key = null;
switch (keyType){
case KEY_TYPE_PRIVATE:
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(keyByte);
key = KeyFactory.getInstance(ALGORITHM).generatePrivate(pkcs8EncodedKeySpec);
break;
case KEY_TYPE_PUBLIC:
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(keyByte);
key = KeyFactory.getInstance(ALGORITHM).generatePublic(x509EncodedKeySpec);
}
//初始化解密Cipher
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(cipherMode,key);
return cipher;
}
/**
* 分段加解密
* @param cipher
* @param strByte
* @param maxBlock
* @return
*/
private static byte[] segment(Cipher cipher, byte[] strByte, int maxBlock) throws Exception {
int length = strByte.length;
int offset = 0;
byte[] resultByte = {};
byte[] cache = {};
while (length - offset > 0){
if (length - offset > maxBlock){
//剩余长度大于最大长度时,则按加解密长度为最大长度,并设置偏移量offset
cache = cipher.doFinal(strByte,offset,maxBlock);
offset += maxBlock;
}else {
//运行到此处代表最后一段加解密,完成后整段加解密完成
cache = cipher.doFinal(strByte,offset,length - offset);
offset = length;
}
//复制resultByte到新的数组, 数组长度为resultByte和cache的长度之和
resultByte = Arrays.copyOf(resultByte, resultByte.length + cache.length);
//将新的加解密字节添加到resultByte的结尾
System.arraycopy(cache,0,resultByte,resultByte.length-cache.length, cache.length);
}
return resultByte;
}
public static void main(String[] args) throws Exception {
KeyPair keyPair = genKeyPair(); //获取KeyPair
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); //获取公钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); //获取私钥
String publicKeyStr = Base64Utils.encodeToString(publicKey.getEncoded());
String privateKeyStr = Base64Utils.encodeToString(privateKey.getEncoded());
System.out.println("公钥: "+publicKeyStr);
System.out.println("私钥: "+privateKeyStr);
String str = "第一次加密";
//公钥加密,私钥解密
System.out.println("***************** 公钥加密,私钥解密 ****************");
String encryptByPublicStr = encrypt(str,publicKeyStr);
System.out.println("公钥加密:"+encryptByPublicStr);
System.out.println("私钥解密:"+decrypt(encryptByPublicStr,privateKeyStr));
System.out.println("");
//私钥加密,公钥解密
System.out.println("***************** 私钥加密,公钥解密 ****************");
String encryptByPrivateStr = encrypt(str,privateKeyStr,KEY_TYPE_PRIVATE);
System.out.println("私钥加密:"+encryptByPrivateStr);
System.out.println("公钥解密:"+decrypt(encryptByPrivateStr,publicKeyStr,KEY_TYPE_PUBLIC));
}
}
版权声明:本文为qq_40260565原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。