import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
public class LXRSAUtils {
private static final String KEY_ALGORITHM = "RSA";
private static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
private static final int MAX_ENCRYPT_BLOCK = 117;
private static final int MAX_DECRYPT_BLOCK = 128;
public static KeyPair getKeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
return keyPair;
}
public static String getPublicKey(KeyPair keyPair){
PublicKey publicKey = keyPair.getPublic();
byte[] bytes = publicKey.getEncoded();
return byte2Base64(bytes);
}
public static String getPrivateKey(KeyPair keyPair){
PrivateKey privateKey = keyPair.getPrivate();
byte[] bytes = privateKey.getEncoded();
return byte2Base64(bytes);
}
public static PublicKey string2PublicKey(String pubStr) throws Exception{
byte[] keyBytes = base642Byte(pubStr);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(keySpec);
return publicKey;
}
public static PrivateKey string2PrivateKey(String priStr) throws Exception{
byte[] keyBytes = base642Byte(priStr);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
return privateKey;
}
public static String byte2Base64(byte[] bytes){
return java.util.Base64.getEncoder().encodeToString(bytes);
}
public static byte[] base642Byte(String base64Key) {
return java.util.Base64.getDecoder().decode(base64Key);
}
public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = data.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
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();
out.close();
return encryptedData;
}
public static String encryptByPublicKey(String data, String publicKey) throws Exception {
byte[] dataBytes = data.getBytes("utf-8");
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicK = keyFactory.generatePublic(x509KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicK);
int inputLen = dataBytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
cache = cipher.doFinal(dataBytes, offSet, MAX_ENCRYPT_BLOCK);
} else {
cache = cipher.doFinal(dataBytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_ENCRYPT_BLOCK;
}
byte[] encryptedData = out.toByteArray();
out.close();
String enResult = Base64.encodeBase64String(encryptedData);
return enResult;
}
public static String decryptByPrivateKey(String encryptedData, String privateKey) throws Exception {
byte[] decodeBytes = Base64.decodeBase64(encryptedData);
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = decodeBytes.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
int offSet = 0;
byte[] cache;
int i = 0;
while (inputLen - offSet > 0) {
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
cache = cipher.doFinal(decodeBytes, offSet, MAX_DECRYPT_BLOCK);
} else {
cache = cipher.doFinal(decodeBytes, offSet, inputLen - offSet);
}
out.write(cache, 0, cache.length);
i++;
offSet = i * MAX_DECRYPT_BLOCK;
}
byte[] decryptedData = out.toByteArray();
out.close();
String decryptInfo = new String(decryptedData, "utf-8");
return decryptInfo;
}
public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateK);
int inputLen = encryptedData.length;
ByteArrayOutputStream out = new ByteArrayOutputStream();
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();
out.close();
return decryptedData;
}
public static String sign(byte[] data, String privateKey) throws Exception {
byte[] keyBytes = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(privateK);
signature.update(data);
return Base64.encodeBase64String(signature.sign());
}
public static String sign(String data, String privateKey) throws Exception {
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
return sign(dataBytes, privateKey);
}
public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {
byte[] keyBytes = Base64.decodeBase64(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
PublicKey publicK = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(publicK);
signature.update(data);
return signature.verify(Base64.decodeBase64(sign));
}
public static boolean verify(String data, String publicKey, String sign) throws Exception {
byte[] dataBytes = data.getBytes(StandardCharsets.UTF_8);
return verify(dataBytes, publicKey, sign);
}
public static void initRsa() throws Exception {
KeyPair keyPair = getKeyPair();
String publicKeyStr = getPublicKey(keyPair);
String privateKeyStr = getPrivateKey(keyPair);
System.out.println("RSA公钥Base64编码:" + publicKeyStr);
System.out.println("RSA私钥Base64编码:" + privateKeyStr);
}
public static void main(String[] args) throws Exception {
String wkPublicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCe11v/ZN1dMP0ehXnw5LQhDKVKB0yE4JKcYvmr+mrao/0P+HXFIeQ4bJjXFIa/BtwJg89CCFxpIT1TSKxGs2b5HK4tNnHpn6UYYrOC/lwfmE7G56qOyxpK8QsWSI8j/U5JLFCPf2Iv3CW4OGSP6BG1KAjOugWqFHi5vX104VDXmwIDAQAB";
String wkPrivateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJ7XW/9k3V0w/R6FefDktCEMpUoHTITgkpxi+av6atqj/Q/4dcUh5DhsmNcUhr8G3AmDz0IIXGkhPVNIrEazZvkcri02cemfpRhis4L+XB+YTsbnqo7LGkrxCxZIjyP9TkksUI9/Yi/cJbg4ZI/oEbUoCM66BaoUeLm9fXThUNebAgMBAAECgYBB7T7Y3MNoB4o3Xc0D59i/kuETvb3LtO4FDKt17uTkxIWnWEeBP5TaunAhbPqUVMOFC3k9ffzlAY/TfmlKmvGUsKBHTJA6YETvtp3bqGyeb4xU6J6/YDIy45ca3MJ+ZLkc7LFVp6ZRHWPKaxCoA2dCbMjOFHEv3EkF3Gq9fA+riQJBAObKROYkB5RWogPSHzWD/klZ/7Nxakld+/2dXMeDK355Ea9tAaYxev8u5NDiRGYo8e0PdPVSo4MAIVdCaK439ucCQQCwMSNmaoXCscgABHHaGil1Bw0CShod+oH2d/NZErecb7oyCZUV/2llTushwp8K6whKe1x8ZfZNBd5lt37q0OctAkB40s/7REWLjUdIhMq985o+wJUzVl70hfWUsruN38f3cF6n3oOMhD8GNYCpMqvoZ+sv1nW+sULVJE5QJn4zJy1lAkA7ycDofRc81RU4JEn6J8yPoL/iWgD40UwOte+G91oFJMi7OBM2LsC2FwylHSTZEJ50n93nfLYStv4b6COSTSdVAkEApgf/0at6okMkIpLgzXla9W+L4z8dX/L2AUIJ9NNyXHSvrMACnaj6O4QZ35kvm8Hm0usmbmaW9r3Pzd38x1F6LQ==";
String key = "kYQyymtMSjbiPV5o";
HashMap<String, Object> param = new HashMap<>();
JSONObject bizData = new JSONObject();
bizData.put("mobile","17600518484");
bizData.put("certId","141124199204090078");
bizData.put("name","张三");
param.put("channelId","105900001");
param.put("timestamp",System.currentTimeMillis());
param.put("bizData",bizData);
System.out.println("【请求明文】"+JSON.toJSONString(param));
String encrypt = LXAESUtil.encrypt(JSON.toJSONString(bizData), key);
param.put("bizData",encrypt);
System.out.println("【AES加密后密文bizData】"+encrypt);
String data = JSON.toJSONString(param, SerializerFeature.SortField,
SerializerFeature.MapSortField,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty,
SerializerFeature.WriteNullListAsEmpty);
String sign = sign(data,wkPrivateKey);
System.out.println("【签名sign】"+sign);
param.put("sign",sign);
System.out.println("【接口调用入参】"+JSON.toJSONString(param));
System.out.println("============================================省略接口调用================================================================");
System.out.println("==================================解密流程开始========================================================");
param.remove("sign",sign);
String result = JSON.toJSONString(param);
boolean verify = verify(result,wkPublicKey,sign);
System.out.println("【验签结果】"+verify);
if(verify){
String decrypt = LXAESUtil.decrypt(encrypt, key);
System.out.println("AES解密后内容:"+decrypt);
JSONObject jsonObject = JSONObject.parseObject(decrypt);
param.put("bizData", jsonObject);
System.out.println("【解密后报文】"+JSON.toJSONString(param));
}
}
}