import kafka.log.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
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;
import java.util.HashMap;
import java.util.Map;
/**
-
@description: RSA加解密工具类
-
@fileName: RSAUtils.java
-
@author: Sure
-
@createAt: 2022/3/7 14:20
-
@updateBy: Sure
-
@remark:
-
*/
@Slf4j
public class RsaUtils {/**
- 加解密算法关键字
*/
public static final String KEY_ALGORITHM = “RSA”;
/**
- 公钥关键字
*/
private static final String PUBLIC_KEY = “RSAPublicKey”;
/**
- 私钥关键字
*/
private static final String PRIVATE_KEY = “RSAPrivateKey”;
/**
- 默认编码
*/
public static final String CHARSET = “UTF-8”;
/**
- 最大加密字节数,超出最大字节数需要分组加密
*/
private static int MAX_ENCRYPT_BLOCK = 117;
/**
- 最大解密字节数,超出最大字节数需要分组解密
*/
private static int MAX_DECRYPT_BLOCK = 256;
/**
- 解密
- @param str 加密的base64串
- @param privateKey base64私钥串
- @return 解密后字符
*/
public static String decrypt(String str, String privateKey) throws Exception {
//64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(str.getBytes(CHARSET));
//base64编码的私钥
byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
//RSA解密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, priKey);
return new String(cipher.doFinal(inputByte), CHARSET);
}
/**
- 加密
- @param data 需要加密的数据
- @param publicKey base64公钥串
- @return 加密后的base64字符串
*/
public static String encrypt(String data, String publicKey) throws Exception {
// 取得公钥
Key key = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes(CHARSET))));
// 对数据加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
return new String(Base64.encodeBase64(cipher.doFinal(data.getBytes(CHARSET))), CHARSET);
}
/**
- 获取base64私钥
- @param keyMap 秘钥
- @return 私钥
*/
public static String getPrivateKeyStr(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return Base64.encodeBase64String(key.getEncoded());
}
/**
- 取得base64公钥
- @param keyMap 秘钥
- @return base64公钥
*/
public static String getPublicKeyStr(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return Base64.encodeBase64String(key.getEncoded());
}
/**
-
初始化秘钥
-
@return 秘钥
-
@throws NoSuchAlgorithmException
*/
public static Map<String, Object> initKey() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(2048);
KeyPair keyPair = keyPairGen.generateKeyPair();
//公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map<String, Object> keyMap = new HashMap<>(5);keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
/**
- 分段解密
- @param inputData 加密的base64字符串
- @param privateKey base64的私钥
- @return 解密后内容
- @throws Exception
*/
public static String decryptByShort(String inputData, String privateKey) throws Exception {
//64位解码加密后的字符串
byte[] inputBytes = Base64.decodeBase64(inputData.getBytes(CHARSET));
//base64编码的私钥
byte[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
//RSA解密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, priKey);
byte[] resultBytes = doFinalBySegment(inputBytes, cipher, MAX_DECRYPT_BLOCK);
return new String(resultBytes, CHARSET);
}
- 加解密算法关键字
/**
-
分段公钥加密
-
@param inputData 需要加密的字符串
-
@param publicKey 公钥
-
@return: 加密后的base64编码
*/
public static String encryptByShort(String inputData, String publicKey) throws Exception {
// 取得公钥
Key key = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(publicKey.getBytes(CHARSET))));
// 对数据加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] resultBytes = doFinalBySegment(inputData.getBytes(CHARSET), cipher, MAX_ENCRYPT_BLOCK);
return new String(Base64.encodeBase64(resultBytes), CHARSET);
}/**
- @Author: TheBigBlue
- @Description: 分段加解密
- @Date: 2019/9/24
- @Return:
**/
private static byte[] doFinalBySegment(byte[] inputBytes, Cipher cipher, int maxLength) throws Exception {
int inputLenth = inputBytes.length;
log.info(“数据超出最大字节数进行分段加解密:maxLength={}, inputLength={}”, maxLength, inputLenth);
// 标识
int offSet = 0;
byte[] cache;
byte[] resultBytes = {};
while (inputLenth - offSet > 0) {
//超出最大字节数分组加密
if (inputLenth - offSet > maxLength) {
cache = cipher.doFinal(inputBytes, offSet, maxLength);
offSet += maxLength;
} else {
//直接加密
cache = cipher.doFinal(inputBytes, offSet, inputLenth - offSet);
offSet = inputLenth;
}
resultBytes = Arrays.copyOf(resultBytes, resultBytes.length + cache.length);
System.arraycopy(cache, 0, resultBytes, resultBytes.length - cache.length, cache.length);
}
return resultBytes;
}
}