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 {
byte
[] inputByte = Base64.decodeBase64(str.getBytes(CHARSET));
byte
[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(
new
PKCS8EncodedKeySpec(keyBytes));
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 {
byte
[] inputBytes = Base64.decodeBase64(inputData.getBytes(CHARSET));
byte
[] keyBytes = Base64.decodeBase64(privateKey.getBytes(CHARSET));
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(
new
PKCS8EncodedKeySpec(keyBytes));
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;
}
}