package com.stylefeng.guns.modular.system.util.zhenglian;
|
|
import com.alibaba.fastjson.JSON;
|
import com.alibaba.fastjson.JSONObject;
|
import com.stylefeng.guns.modular.system.util.SpringContextsUtil;
|
import com.stylefeng.guns.modular.system.util.UUIDUtil;
|
import com.stylefeng.guns.modular.system.util.zhenglian.model.MessageBody;
|
import com.stylefeng.guns.modular.system.util.zhenglian.model.TradeTerminalInfo;
|
import com.stylefeng.guns.modular.system.util.zhenglian.model.ZLUserInfo;
|
import com.zlpay.assist.encrypt.sm4.SM4Util;
|
import com.zlpay.assist.sign.sm2.SM2Cert;
|
import com.zlpay.assist.sign.sm2.SM2Util;
|
import lombok.extern.slf4j.Slf4j;
|
import org.apache.commons.lang.RandomStringUtils;
|
|
import java.io.File;
|
import java.io.FileInputStream;
|
import java.io.IOException;
|
import java.security.cert.X509Certificate;
|
import java.text.SimpleDateFormat;
|
import java.util.Base64;
|
import java.util.Date;
|
import java.util.HashMap;
|
import java.util.Map;
|
|
/**
|
* @author zhibing.pu
|
* @Date 2025/7/28 14:22
|
*/
|
@Slf4j
|
public class ZhengLianUtil {
|
|
private static ZhengLianConfig zhengLianConfig = SpringContextsUtil.getBean(ZhengLianConfig.class).getZhengLianConfig();
|
|
|
|
|
|
/**
|
* 获取用户详情
|
* @param appUserId
|
* @param tradeTerminalInfo
|
* @return
|
* @throws Exception
|
*/
|
public static ZLUserInfo getUserInfo(String appUserId, TradeTerminalInfo tradeTerminalInfo) throws Exception {
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
Map<String,String> headerMap = new HashMap<String,String>();
|
MessageBody body = new MessageBody();
|
headerMap.put("msgId", UUIDUtil.getRandomCode());
|
headerMap.put("merchNo", "B00000871");
|
headerMap.put("txCode", "ZLPAY.ACC.T0009");
|
headerMap.put("version", "1.0.1");
|
headerMap.put("signa", "1");
|
headerMap.put("signNo", zhengLianConfig.getSignNo());
|
headerMap.put("encrp", "1");
|
headerMap.put("encrpNo", zhengLianConfig.getEncrpNo());
|
headerMap.put("timestamp", sdf.format(new Date()));
|
log.info("【证联获取用户信息】请求头报文:"+JSON.toJSONString(headerMap));
|
|
Map<String, Object> map = new HashMap<>();
|
map.put("appId", zhengLianConfig.getAppid());
|
map.put("appUserId", appUserId);
|
map.put("tradeTerminalInfo", tradeTerminalInfo);
|
String reqBO = JSON.toJSONString(map);
|
log.info("【证联获取用户信息】请求体报文:"+reqBO);
|
// 生成对称加密秘钥
|
String key = ZhengLianUtil.generateKey(16);
|
// 加密数据
|
String jsonData = SM4Util.sm4EcbEncrypt(key, reqBO, "NoPadding");
|
//加密对称加密的秘钥
|
// 获取公钥
|
String publicKey = ZhengLianUtil.getPublicKey();
|
String secrtKey = SM2Util.encrypt(publicKey, key);
|
|
// 将密文放入body
|
body.setData(jsonData);
|
body.setSign(ZhengLianUtil.sign(jsonData));
|
body.setSecret(secrtKey);
|
log.info("【证联获取用户信息】请求体密文报文:"+JSON.toJSONString(body));
|
String result = ZLHttpClientUtil.doPost(zhengLianConfig.getUrl(), headerMap, JSON.toJSONString(body));
|
|
log.info("【证联获取用户信息】应答内容:"+ result);
|
MessageBody respBody = JSON.parseObject(result,MessageBody.class);
|
// 验签
|
boolean checkResult = SM2Util.verify(publicKey, zhengLianConfig.getEncrpNo(), respBody.getSign(), respBody.getData());
|
log.info("【证联获取用户信息】验签结果:" + checkResult);
|
// 获取私钥
|
String privateKey = ZhengLianUtil.getPrivateKey();
|
// 解密对称秘钥
|
String k = SM2Util.decrypt(privateKey, respBody.getSecret());
|
log.info("【证联获取用户信息】对称秘钥:" + k);
|
// 解密业务报文
|
String backData = SM4Util.sm4EcbDecrypt(k, respBody.getData());
|
log.info("【证联获取用户信息】返回业务报文:" + backData);
|
JSONObject jsonObject = JSON.parseObject(backData);
|
String sysRtnCode = jsonObject.getString("sysRtnCode");
|
if(!"000000".equals(sysRtnCode)){
|
log.error("【证联获取用户信息】查询用户信息失败!{}", jsonObject.getString("sysRtnMsg"));
|
throw new Exception(jsonObject.getString("sysRtnMsg"));
|
}
|
JSONObject bizData = jsonObject.getJSONObject("bizData");
|
String resCode = bizData.getString("resCode");
|
if("F010900".equals(resCode)){
|
return null;
|
}
|
if(!"S010000".equals(resCode)){
|
log.error("【证联获取用户信息】查询用户信息失败!{}", bizData.getString("resMsg"));
|
throw new Exception(jsonObject.getString("resMsg"));
|
}
|
JSONObject resData = bizData.getJSONObject("resData");
|
ZLUserInfo zlUserInfo = resData.toJavaObject(ZLUserInfo.class);
|
return zlUserInfo;
|
}
|
|
|
|
|
|
|
|
/**
|
* @Description: 从公钥证书获取公钥串
|
* @return
|
* @return String
|
* @throws
|
* @author: tsl
|
* @date: 2019年4月19日 下午9:07:56
|
*/
|
public static String getPublicKey() {
|
String publicKey = "";
|
FileInputStream inputStream = null;
|
try {
|
inputStream = new FileInputStream(new File(zhengLianConfig.getCer()));
|
X509Certificate publicCert = SM2Cert.getPublicCert(inputStream);
|
publicKey = Base64.getEncoder().encodeToString(publicCert.getEncoded());
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
if (inputStream != null) {
|
try {
|
inputStream.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return publicKey;
|
}
|
|
/**
|
* @Description: 从私钥证书获取私钥传
|
* @return
|
* @return String
|
* @throws
|
* @author: tsl
|
* @date: 2019年4月19日 下午9:08:00
|
*/
|
public static String getPrivateKey() {
|
String privateKey = "";
|
FileInputStream inputStream = null;
|
try {
|
inputStream = new FileInputStream(new File(zhengLianConfig.getSm2()));
|
byte[] priBytes = SM2Cert.getPrivateCert(inputStream);
|
privateKey = SM2Cert.getPrivateKey(zhengLianConfig.getPassword(), priBytes);
|
} catch (Exception e) {
|
e.printStackTrace();
|
} finally {
|
if (inputStream != null) {
|
try {
|
inputStream.close();
|
} catch (IOException e) {
|
e.printStackTrace();
|
}
|
}
|
}
|
return privateKey;
|
}
|
/**
|
* @Description: 生成对称加密秘钥
|
* @return String
|
* @throws
|
* @author: syuf
|
* @date: 2018年11月8日 下午5:50:05
|
*/
|
public static String generateKey(int length) {
|
return RandomStringUtils.randomAlphanumeric(length);
|
}
|
/**
|
* @Description: 签名
|
* @param data
|
* @return String
|
* @throws
|
* @author: syuf
|
* @date: 2018年11月15日 下午2:19:01
|
*/
|
public static String sign(String data) {
|
try {
|
// 获取私钥
|
String privateKey = getPrivateKey();
|
return com.zlpay.assist.sign.sm2.SM2Util.sign(privateKey, zhengLianConfig.getSignNo(), data);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
return "";
|
}
|
}
|