原文链接:https://blog.csdn.net/qq_37469055/article/details/115188081
一:RSA非对称加密
RSA是一种常用的非对称加密算法,加密和加密使用不同的密钥,常用于要求安全性较高的加密场景,比如接口的验签和接口数据的加密与解密。与非对称加密算法对比,其安全性较高,但是加密性能却比较低,不适合高并发场景,一般只加密少量的数据。
二:AES对称加密
AES是一种最常见的对称加密算法(微信小程序加密传输就是用这个加密算法的),加密和解密使用的是相同的密钥。其加密性能好,加密解密速度非常快,内存需求低,适用于经常发送数据的场合。
三:RSA+AES实现接口验签和请求参数的加密与解密
我们经常需要在我们自己开发的系统上,开发一些接口供第三方调用,那么这个时候,对我们接口的安全性要求就比较高了,尤其是那种需要传输比较私密的信息的时候,其对安全性的要求就更高了。
实现思路
调用方:
使用AES对称加密算法对业务请求参数进行加密后传输
使用RSA非对称加密算法对AES的密钥进行公钥加密后传输
使用RSA的私钥对请求参数进行签名
接收方:
获取到请求参数后,对参数进行验签和业务参数的解密
问题:为什么要对AES的密钥进行RSA公钥加密后传输?
AES是对称加密算法,加密和解密的密钥都是同一个,为了防止被别人恶意获取到该密钥,然后对我们的业务请求参数进行解密,我们需要将AES密钥进行非对称加密后再进行传输
代码实现
AESUtils :AES工具类
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
/**
* @author
* @program
* @description
* @create 2022/10/17 10:57
**/
public class AESUtils {
/**
* 编码格式
*/
public static final String CHARSET = "UTF-8";
/**
* 加密算法
*/
public static final String AES_ALGORITHM = "AES";
/**
* 生成密钥
* @return
*/
public static String generateKey() {
try {
//1.构造密钥生成器,指定为AES算法,不区分大小写
KeyGenerator keygen = KeyGenerator.getInstance(AES_ALGORITHM);
//2.生成一个128位的随机源
keygen.init(128, new SecureRandom());
//3.产生原始对称密钥
SecretKey secretKey = keygen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] byteKey = secretKey.getEncoded();
//5.返回密钥
return Hex.encodeHexString(byteKey);
}catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
//如果有错就返加nulll
return null;
}
/**
* 加密
* @param thisKey 密钥
* @param data 数据
* @return 加密后的数据
*/
public static String encode(String thisKey, String data) {
try {
//1.转换KEY
Key key = new SecretKeySpec(Hex.decodeHex(thisKey), AES_ALGORITHM);
//2.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
//3.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.ENCRYPT_MODE, key);
//4.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
byte[] byteEncode = data.getBytes(CHARSET);
//5.根据密码器的初始化方式--加密:将数据加密
byte[] result = cipher.doFinal(byteEncode);
//6.将字符串返回
return Hex.encodeHexString(result);
} catch (DecoderException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
e.printStackTrace();
}
//如果有错就返加nulll
return null;
}
/**
* 解密
* @param thisKey 密钥
* @param data 加密的数据
* @return 解密后的数据
*/
public static String decode(String thisKey, String data) {
try {
//1.转换KEY
Key key = new SecretKeySpec(Hex.decodeHex(thisKey), AES_ALGORITHM);
//2.根据指定算法AES自成密码器
Cipher cipher = Cipher.getInstance(AES_ALGORITHM);
//3.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
cipher.init(Cipher.DECRYPT_MODE, key);
//4.将加密并编码后的内容解码成字节数组
byte[] byteContent = Hex.decodeHex(data);
//5.解密
byte[] byteDecode = cipher.doFinal(byteContent);
//6.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
return new String(byteDecode, CHARSET);
} catch (DecoderException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
e.printStackTrace();
}
//如果有错就返加nulll
return null;
}
public static void main(String[] args) {
String key = generateKey();
System.out.println("生成的密钥为:" + key);
// String pubKey = "6aa7066f738828f333b1bb84b62606c6";
// String priKey = "6aa7066f738828f333b1bb84b62606c6";
String data = "使用AES对称加密,请输入加密的规则使用AES对称加密AAAAAABBBBB";
String encodeData = encode(key, data);
System.out.println("加密后的数据为:" + encodeData);
String decodeData = decode(key, encodeData);
System.out.println("解密后的数据为:" + decodeData);
}
}
RSAUtils :RSA工具类
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
import javax.crypto.Cipher;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Method;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.*;
/**
* @author
* @program
* @description
* @create 2022/10/17 10:57
**/
public class RSAUtils {
/**
* 编码格式
*/
public static final String CHARSET = "UTF-8";
/**
* 加密算法
*/
public static final String RSA_ALGORITHM = "RSA";
/**
* 定义签名算法
*/
private final static String KEY_RSA_SIGNATURE = "MD5withRSA";
/**
* 得到公钥
*
* @param publicKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过X509编码的Key指令获得公钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
return (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
}
/**
* 得到私钥
*
* @param privateKey 密钥字符串(经过base64编码)
* @throws Exception
*/
public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
//通过PKCS#8编码的Key指令获得私钥对象
KeyFactory keyFactory = KeyFactory.getInstance(RSA_ALGORITHM);
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
return key;
}
/**
* 公钥加密
*
* @param data
* @param publicKey
* @return
*/
public static String publicEncrypt(String data, RSAPublicKey publicKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return Base64.encodeBase64URLSafeString(rsaSplitCodec(cipher, Cipher.ENCRYPT_MODE, data.getBytes(CHARSET), publicKey.getModulus().bitLength()));
} catch (Exception e) {
throw new RuntimeException("加密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 私钥解密
*
* @param data
* @param privateKey
* @return
*/
public static String privateDecrypt(String data, RSAPrivateKey privateKey) {
try {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return new String(rsaSplitCodec(cipher, Cipher.DECRYPT_MODE, Base64.decodeBase64(data), privateKey.getModulus().bitLength()), CHARSET);
} catch (Exception e) {
throw new RuntimeException("解密字符串[" + data + "]时遇到异常", e);
}
}
/**
* 分段加解密
*
* @param cipher
* @param opmode
* @param datas
* @param keySize
* @return
*/
private static byte[] rsaSplitCodec(Cipher cipher, int opmode, byte[] datas, int keySize) {
int maxBlock = 0;
if (opmode == Cipher.DECRYPT_MODE) {
maxBlock = keySize / 8;
} else {
maxBlock = keySize / 8 - 11;
}
ByteArrayOutputStream
out = new ByteArrayOutputStream();
int offSet = 0;
byte[] buff;
int i = 0;
try {
while (datas.length > offSet) {
if (datas.length - offSet > maxBlock) {
buff = cipher.doFinal(datas, offSet, maxBlock);
} else {
buff = cipher.doFinal(datas, offSet, datas.length - offSet);
}
out.write(buff, 0, buff.length);
i++;
offSet = i * maxBlock;
}
} catch (Exception e) {
throw new RuntimeException("加解密阀值为[" + maxBlock + "]的数据时发生异常", e);
}
byte[] resultDatas = out.toByteArray();
IOUtils.closeQuietly(out);
return resultDatas;
}
/**
* 用私钥对信息生成数字签名
*
* @param data 加密数据
* @param privateKey 私钥
*/
public static String sign(byte[] data, String privateKey) {
String str = "";
try {
// 解密由base64编码的私钥
byte[] bytes = decryptBase64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs = new PKCS8EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(RSA_ALGORITHM);
// 取私钥对象
PrivateKey key = factory.generatePrivate(pkcs);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initSign(key);
signature.update(data);
str = encryptBase64(signature.sign());
} catch (Exception e) {
e.printStackTrace();
}
return str;
}
/**
* 校验数字签名
*
* @param data 加密数据
* @param publicKey 公钥
* @param sign 数字签名
* @return 校验成功返回true,失败返回false
*/
public static boolean verify(byte[] data, String publicKey, String sign) {
boolean flag = false;
try {
// 解密由base64编码的公钥
byte[] bytes = decryptBase64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
// 指定的加密算法
KeyFactory factory = KeyFactory.getInstance(RSA_ALGORITHM);
// 取公钥对象
PublicKey key = factory.generatePublic(keySpec);
// 用公钥验证数字签名
Signature signature = Signature.getInstance(KEY_RSA_SIGNATURE);
signature.initVerify(key);
signature.update(data);
flag = signature.verify(decryptBase64(sign));
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* BASE64 解密
*
* @param key 需要解密的字符串
* @return 字节数组
*/
public static byte[] decryptBase64(String key) {
return Base64.decodeBase64(key);
}
/**
* BASE64 加密
*
* @param key 需要加密的字节数组
* @return 字符串
*/
public static String encryptBase64(byte[] key) {
return new String(Base64.encodeBase64(key));
}
/**
* bean转map
*
* @param obj
* @return
*/
public static Map<String, Object> beanToMap(Object obj) {
if (obj == null) {
return null;
}
Map<String, Object> map = new HashMap<>();
try {
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (PropertyDescriptor property : propertyDescriptors) {
String key = property.getName();
// 过滤class属性
if (!"class".equals(key)) {
// 得到property对应的getter方法
Method getter = property.getReadMethod();
Object value = getter.invoke(obj);
if (value == null) {
continue;
}
map.put(key, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return map;
}
/**
* 按照红黑树(Red-Black tree)的 NavigableMap 实现
* 按照字母大小排序
*
* @param map
* @return
*/
public static Map<String, Object> sort(Map<String, Object> map) {
if (map == null) {
return null;
}
Map<String, Object> result = new TreeMap<>((Comparator<String>) (o1, o2) -> {
return o1.compareTo(o2);
});
result.putAll(map);
return result;
}
/**
* 组合参数
*
* @param map
* @return 如:key1Value1Key2Value2....
*/
public static String groupStringParam(Map<String, Object> map) {
if (map == null) {
return null;
}
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, Object> item : map.entrySet()) {
if (item.getValue() != null) {
sb.append(item.getKey());
if (item.getValue() instanceof List) {
sb.append(JSON.toJSONString(item.getValue()));
} else {
sb.append(item.getValue());
}
}
}
return sb.toString();
}
/**
* 将Hex String转换为Byte数组
*
* @param hexString
* @return
*/
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
/**
* @brief char to byte
*/
public static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
public static void main(String[] args) throws Exception {
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFRIbGz6PJm3kboIzXr8Vw4Yv80xWwpNRNELVVTeXQXlB0kZ5-XfBdqDW3PkVM5ePxn1tNfiHxZvvgKr80Y5Un51-987lS8O2gh4juIOpIQ9LEHbEcoABtH2gGVmDGEdVtzfOXTSiDPW_0E6bAbD5Yzmw2Uf8e_bsiMH_sjIwiQIDAQAB";
String privateKey = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMIVEhsbPo8mbeRugjNevxXDhi_zTFbCk1E0QtVVN5dBeUHSRnn5d8F2oNbc-RUzl4_GfW01-IfFm--AqvzRjlSfnX73zuVLw7aCHiO4g6khD0sQdsRygAG0faAZWYMYR1W3N85dNKIM9b_QTpsBsPljObDZR_x79uyIwf-yMjCJAgMBAAECgYEAo8ZyE-umm9e67gOO3Vh7eRsYdggiCCiDdgfayfjyQzId57xQeodYVioLyaSIkCqMH-hIWUss4S2Qy8dRAqy3JBs6wrXIfWCMYMS1yRLJ1zbZvflCKgylTd3VY6iFfOeOviGTetVtr0iVesV0CrP_N9_iQFqMOCyJXAI8oGFGv90CQQDpv9W1eUdrxJ9wvf8nDFtKg-AdNQkJXlckyi2ZdSzp2q6o3_2O6SAIv1Rjal9SJkVnDnQFFx-a6JhoPER3LWnLAkEA1I6aHXCmSlhg1f3a-RjJyWmGVL05agOWx-HqfBv9WrsKz3khBLFtRu_MG52bazVOm8cZ3du422bEw0bQr8WUewJAewsSMd7Pa7kqvKwm3aUxgP3-QSGjyhyw_pq2eismI0uL2TVfQZUR2cjtYQ-jcZjXu7Ht_Kf5aQ-6-lOPLrTnFQJAMHEvfnYl79ukdiCcvxh_JIAANV_KrfaTbop2PkLCwuLN2-rnM4KcPQZ5pfGNcil7-NSveHiS8K3DOh3xgZ2t8QJAccgZKfAU7WV9nL1ZOMpqjIfl5KbwyChsY2oU7GWLinUEL5kjqgU1Y6LWIrzuPGGc2eL2iHXp2JCepKYMvwTFKw";
System.out.println("公钥加密——私钥解密");
String str = "code_cayden";
System.out.println("\r明文:\r\n" + str);
System.out.println("\r明文大小:\r\n" + str.getBytes().length);
String encodedData = RSAUtils.publicEncrypt(str, RSAUtils.getPublicKey(publicKey));
System.out.println("密文:\r\n" + encodedData);
String decodedData = RSAUtils.privateDecrypt(encodedData, RSAUtils.getPrivateKey(privateKey));
System.out.println("解密后文字: \r\n" + decodedData);
}
}
RequestApiParam :接口参数对象
import lombok.Data;
import javax.validation.constraints.NotBlank;
/**
* @author
* @program
* @description
* @create 2022/10/17 10:57
**/
@Data
public class RequestApiParam {
/**
* 接口id (可空)
*/
private String serviceId;
/**
* 商户id (非空)
*/
@NotBlank(message = "appid不能为空")
private String appId;
/**
* 参数签名 (非空)
*/
@NotBlank(message = "参数签名不能为空")
private String sign;
/**
* 对称加密key (非空)
*/
@NotBlank(message = "对称加密key不能为空")
private String aseKey;
/**
* 时间戳,精确到毫秒 (非空)
*/
private Long timestamp;
/**
* 请求的业务参数(AES加密后传入,可空)
*/
@NotBlank(message = "请求的业务参数不能为空")
private String body;
}
RSAKeyGenerator 生成RSA密钥对
import org.apache.commons.codec.binary.Base64;
import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author
* @program
* @description
* @create 2022/10/17 10:57
**/
public class RSAKeyGenerator {
/**
* 加密算法
*/
public static final String RSA_ALGORITHM = "RSA";
/**
* 公钥key
*/
private static final String PUBLIC_KEY = "publicKey";
/**
* 私钥KEY
*/
private static final String PRIVATE_KEY = "privateKey";
/**
* APPID
*/
private static final String APPID = "appId";
/**
* 生成公钥和私钥
*
* @param keySize
* @return
*/
public static Map<String, String> createKeys(int keySize) {
//为RSA算法创建一个KeyPairGenerator对象
KeyPairGenerator kpg;
try {
kpg = KeyPairGenerator.getInstance(RSA_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
throw new IllegalArgumentException("No such algorithm-->[" + RSA_ALGORITHM + "]");
}
//初始化KeyPairGenerator对象,密钥长度
kpg.initialize(keySize);
//生成密匙对
KeyPair keyPair = kpg.generateKeyPair();
//得到公钥
Key publicKey = keyPair.getPublic();
String publicKeyStr = Base64.encodeBase64URLSafeString(publicKey.getEncoded());
//得到私钥
Key privateKey = keyPair.getPrivate();
String privateKeyStr = Base64.encodeBase64URLSafeString(privateKey.getEncoded());
Map<String, String> keyPairMap = new HashMap<String, String>();
keyPairMap.put(PUBLIC_KEY, publicKeyStr);
keyPairMap.put(PRIVATE_KEY, privateKeyStr);
keyPairMap.put(APPID, UUID.randomUUID().toString());
return keyPairMap;
}
public static void main(String[] args) {
Map<String, String> keyMap = RSAKeyGenerator.createKeys(1024);
String publicKey = keyMap.get(PUBLIC_KEY);
String privateKey = keyMap.get(PRIVATE_KEY);
String appId = keyMap.get(APPID);
System.out.println("公钥: " + publicKey);
System.out.println("私钥: " + privateKey);
System.out.println("appId: " + appId);
}
}
测试类
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import java.util.HashMap;
import java.util.Map;
/**
* @author
* @program
* @description
* @create 2022/10/17 10:57
**/
public class RequestTest {
/**
* 公钥key
*/
private static final String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCJAs7g-BKF15KUKxec-H2GC9Q22FMyho_AyByGqrM2uNWnBRQudE3wEWloi2PVGQ62vsTFUclNef2_xvdYWjF4TusUv_e9qwEypOyqQIeNUYmuUbJd_6iCUr2M9kqwj_KT2J106N1bkwRYSu0pCT_JoW7hTomRYXM3P235Bn8L-QIDAQAB";
/**
* 私钥KEY
*/
private static final String PRIVATE_KEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAIkCzuD4EoXXkpQrF5z4fYYL1DbYUzKGj8DIHIaqsza41acFFC50TfARaWiLY9UZDra-xMVRyU15_b_G91haMXhO6xS_972rATKk7KpAh41Ria5Rsl3_qIJSvYz2SrCP8pPYnXTo3VuTBFhK7SkJP8mhbuFOiZFhczc_bfkGfwv5AgMBAAECgYAscZ_ANFh12C7xJ2VagvTc5btqKxQZ4LKC-6bdPEQ0LRMJQcmBJDMf-9Xwlr7EooM2Xn2f8F7XZgodCqKzo1ZGUH9ZXusQKcEXr6b6sfREfIuHIuMoeksMEfCyV-7yZG2k2aHtExfn7rz-LJO-uX28HWvhomKxOlyfbpBhM60eAQJBANri0-Z39bpFs73Dq8ZghqaoV-5T_mhGTkQuWs7VhL83AnF2OZOECW9cwcP20nV5w5_Tm2izSqVmX_6Hq5UEGsECQQCgPgjHblTMHyx6lPIu4Oyr0b84b34f0yDi37qneOZ2EX78yhEQ3dSLwh4ToBcNlZ6Zn8_rZX74SSxsjdIuXdc5AkAKRE1wJ_xMqmxN4Fm0Sl7GfmrxcNskBPgy1oHH5df-KBRjQgpdUvomURF9oZwpinaUjpZhiNddfrnN9IslyDWBAkBC98n5ds2vhPO0wxy3pL6kTAMrVcUTDcw3pKLALNG71DIK-XPKZbrXMagaMZSQ08-1ikl9qiw3HXWYZGjLgeJZAkEAp1U6zcjarlH2xy2NGbdqBelebufxl9MXi6swtSqRE8HewxPgiAuSzDNwjM4S0vNYtsdSB-Zhi8mDXyckitM2zQ";
/**
* appid
*/
private static final String APP_ID = "445d748d-91fd-48a5-a1a5-1dbf14b63fb7";
public static void main(String[] args) throws Exception {
/*****调用方(请求方)*****/
//业务参数
Map<String, Object> businessParams = new HashMap<>();
businessParams.put("name", "testName");
businessParams.put("content", "testContent");
RequestApiParam jsonRequest = new RequestApiParam();
jsonRequest.setAppId(APP_ID);
long currentTimeMillis = System.currentTimeMillis();
jsonRequest.setTimestamp(currentTimeMillis);
//使用AES密钥,并对密钥进行rsa公钥加密
String aseKey = AESUtils.generateKey();
String aseKeyStr = RSAUtils.publicEncrypt(aseKey, RSAUtils.getPublicKey(PUBLIC_KEY));
jsonRequest.setAseKey(aseKeyStr);
//请求的业务参数进行加密
String body = "";
try {
body = AESUtils.encode(aseKey, JSONObject.toJSONString(businessParams));
} catch (Exception e) {
throw new RuntimeException("报文加密异常", e);
}
jsonRequest.setBody(body);
//json转map
Map<String, Object> paramMap = RSAUtils.beanToMap(jsonRequest);
paramMap.remove("sign");
//私钥签名
String sign = RSAUtils.sign(RSAUtils.hexStringToBytes(APP_ID + currentTimeMillis), PRIVATE_KEY);
jsonRequest.setSign(sign);
System.out.println("请求参数:" + jsonRequest);
/*****调用方*****/
/*****接收方*****/
//验签
Map<String, Object> paramMap2 = RSAUtils.beanToMap(jsonRequest);
paramMap2.remove("sign");
//签名验证 通过appid以及时间戳验签
boolean verify = RSAUtils.verify(RSAUtils.hexStringToBytes("" + paramMap2.get("appId") + paramMap2.get("timestamp")), PUBLIC_KEY, jsonRequest.getSign());
if (!verify) {
throw new RuntimeException("签名验证失败");
}
//私钥解密,获取aseKey
String aseKey2 = RSAUtils.privateDecrypt(jsonRequest.getAseKey(), RSAUtils.getPrivateKey(PRIVATE_KEY));
if (!StringUtils.isEmpty(jsonRequest.getBody())) {
// 解密请求报文
String requestBody = "";
try {
requestBody = AESUtils.decode(aseKey2, jsonRequest.getBody());
} catch (Exception e) {
throw new RuntimeException("请求参数解密异常");
}
System.out.println("业务参数解密结果:" + requestBody);
}
/*****接收方*****/
}
}