package com.hoyo.common.core.utils;

import com.hoyo.common.core.utils.uuid.UUID;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.KeyFactory;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RSAUtil {
/**
* 加密算法RSA
*/
private static final String KEY_ALGORITHM = "RSA";

/**
* RSA最大加密明文大小
*/
private static final int MAX_ENCRYPT_BLOCK = 117;

/**
* RSA最大解密密文大小
*/
private static final int MAX_DECRYPT_BLOCK = 256;


/**
* Method: decryptBASE64
* description: 解码返回byte
*
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptBASE64(String key) throws Exception {
return (new BASE64Decoder()).decodeBuffer(key);
}

/**
* Method: encryptBASE64
* description: 编码返回字符串
*
* @param key
* @return
* @throws Exception
*/
public static String encryptBASE64(byte[] key) throws Exception {
return (new BASE64Encoder()).encodeBuffer(key);
}

/**
* 获取base64加密后的字符串的原始公钥
*
* @param keyStr
* @return
* @throws Exception
*/
public static Key getPublicKeyFromBase64KeyEncodeStr(String keyStr) throws Exception {
byte[] keyBytes = decryptBASE64(keyStr);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
Key publicKey = KeyFactory.getInstance(KEY_ALGORITHM).generatePublic(x509KeySpec);
return publicKey;
}

/**
* 获取base64加密后的字符串的原始私钥
*
* @param keyStr
* @return
* @throws Exception
*/
public static Key getPrivateKeyFromBase64KeyEncodeStr(String keyStr) throws Exception {
byte[] keyBytes = decryptBASE64(keyStr);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
Key privateKey = KeyFactory.getInstance(KEY_ALGORITHM).generatePrivate(pkcs8KeySpec);
return privateKey;
}

/**
* Method: encrypt
* description: 公钥分段加密
*
* @param dataStr 加密内容,明文
* @param publicKeyStr 公钥内容
* @return 密文
* @throws Exception
*/
public static String encrypt(String dataStr, String publicKeyStr) throws Exception {
ByteArrayOutputStream out = null;
String encodedDataStr = null;
try {
out = new ByteArrayOutputStream();
byte[] data = dataStr.getBytes("utf-8");
// 获取原始公钥
Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, decodePublicKey);
int inputLen = data.length;
int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段加密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(data, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
encodedDataStr = new String(encryptBASE64(encryptedData));
} catch (Exception e) {
throw e;
} finally {
try {
out.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
return encodedDataStr;
}

/**
* Method: encrypt
* description: 私钥分段解密
*
* @return 明文
* @throws Exception
*/
public static String decrypt(String dataStr, String privateKey) throws Exception {
ByteArrayOutputStream out = null;
String decodedDataStr = null;
try {
out = new ByteArrayOutputStream();

byte[] encryptedData = decryptBASE64(dataStr);
// 获取原始私钥
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKey);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, decodePrivateKey);
int inputLen = encryptedData.length;

int offSet = 0;
byte[] cache;
int i = 0;
// 对数据分段解密
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
decodedDataStr = new String(decryptedData, "utf-8");
} catch (Exception e) {
throw e;
} finally {
try {
out.close();
} catch (Exception e2) {
// TODO: handle exception
}
}
return decodedDataStr;
}

public static void main(String[] args) {
// 公钥
String publicKey = "";

// 私钥
String privateKey = "";

/**
* 加密及获取签名
*/
// 源报文(未加密)
try {
for (int i = 0; i < 10; i++) {
String msg = "USERID=" + UUID.fastUUID() + "&MOBILE=1888888888";
String enc_msg = RSAUtil.encrypt(msg, publicKey);
BASE64Encoder encoder = new BASE64Encoder();
enc_msg = encoder.encode(enc_msg.getBytes("UTF-8"));
enc_msg = enc_msg.replaceAll("\r\n", "").replaceAll("\r", "").replaceAll("\n", "");

System.out.println("------------------------");
System.out.println(enc_msg);
}
// 公钥加密得到密文并使用base64处理

// 根据源报文+私钥获得MD5签名
// String mac_info = SignMD5Utils.getMD5(msg + privateKey);

/**
* 解密及验签
*/
// base64逆处理并用私钥解密
BASE64Decoder decoder = new BASE64Decoder();
String decoStr = new String(decoder.decodeBuffer(""), StandardCharsets.UTF_8);
String dec_msg = RSAUtil.decrypt(decoStr, privateKey);
System.out.println("------------解密密------------");
System.out.println(dec_msg);



} catch (Exception e) {
e.printStackTrace();
}
}
}
posted on 2024-05-15 09:56  独醉笑清风  阅读(2)  评论(0编辑  收藏  举报