记得上下班打卡 | git大法好,push需谨慎

Commit cb347737 authored by anjiabin's avatar anjiabin

提交unionpay代码

parent 97b35e40
......@@ -4,7 +4,9 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.env.Environment;
import java.net.InetAddress;
......@@ -12,6 +14,7 @@ import java.util.Arrays;
@Slf4j
@SpringBootApplication(scanBasePackages = {"com.liquidnet"})
@EnableConfigurationProperties
public class ServiceDragonApplication implements CommandLineRunner {
@Autowired
private Environment environment;
......
......@@ -2,6 +2,8 @@ package com.liquidnet.service.dragon.channel.unionpay.sdk;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.nio.charset.Charset;
......@@ -16,8 +18,13 @@ import static com.liquidnet.service.dragon.channel.unionpay.sdk.SDKConstants.*;
* @date 2018-12-10 下午2:44:37
*/
@Slf4j
@Component
public class QrcService {
@Autowired
private SDKConfig sdkConfig;
@Autowired
private CertUtil certUtil;
/**
* 请求报文签名(使用配置文件中配置的私钥证书或者对称密钥签名)<br>
* 功能:对请求报文进行签名,并计算赋值certid,signature字段并返回<br>
......@@ -25,10 +32,10 @@ public class QrcService {
* @param encoding 上送请求报文域encoding字段的值<br>
* @return 签名后的map对象<br>
*/
public static Map<String, String> sign(Map<String, String> reqData,String encoding) {
return signByCertInfo(reqData, SDKConfig.getConfig().getSignCertPath(), SDKConfig.getConfig().getSignCertPwd(), encoding);
public Map<String, String> sign(Map<String, String> reqData,String encoding) {
return signByCertInfo(reqData, sdkConfig.getSignCertPath(), sdkConfig.getSignCertPwd(), encoding);
}
/**
* 多证书签名(通过传入私钥证书路径和密码签名)<br>
* 功能:如果有多个商户号接入银联,每个商户号对应不同的证书可以使用此方法:传入私钥证书和密码(并且在acp_sdk.properties中 配置 acpsdk.singleMode=false)<br>
......@@ -38,7 +45,7 @@ public class QrcService {
* @param encoding 上送请求报文域encoding字段的值<br>
* @return 签名后的map对象<br>
*/
public static Map<String, String> signByCertInfo(Map<String, String> reqData, String certPath,
public Map<String, String> signByCertInfo(Map<String, String> reqData, String certPath,
String certPwd, String encoding) {
Map<String, String> data = SDKUtil.filterBlank(reqData);
......@@ -62,14 +69,14 @@ public class QrcService {
try {
if (VERSION_1_0_0.equals(version)) {
//被扫脱机码两个接口无视配置固定按sha256withrsa处理。下面两个ifelse别改变顺序。
if (QRC_SIGNTYPE_SHA256WITHRSA.equals(signType)
if (QRC_SIGNTYPE_SHA256WITHRSA.equals(signType)
|| "0420000903".equals(reqType)
|| "0410000903".equals(reqType)) {
data.put(SDKConstants.param_certId, CertUtil.getCertIdByKeyStoreMap(certPath, certPwd));
data.put(SDKConstants.param_certId, certUtil.getCertIdByKeyStoreMap(certPath, certPwd));
data.put(SDKConstants.param_signature, SDKUtil.signRsa2(data, certPath, certPwd, encoding));
return data;
} else if (QRC_SIGNTYPE_SHA1WITHRSA.equals(signType)) {
data.put(SDKConstants.param_certId, CertUtil.getCertIdByKeyStoreMap(certPath, certPwd));
data.put(SDKConstants.param_certId, certUtil.getCertIdByKeyStoreMap(certPath, certPwd));
data.put(SDKConstants.param_signature, SDKUtil.signRsa(data, certPath, certPwd, encoding));
return data;
} else if (QRC_SIGNTYPE_SM3WITHSM2.equals(signType)) {
......@@ -91,14 +98,14 @@ public class QrcService {
* @param encoding 上送请求报文域encoding字段的值<br>
* @return true 通过 false 未通过<br>
*/
public static boolean validate(Map<String, String> resData, String encoding) {
public boolean validate(Map<String, String> resData, String encoding) {
log.info("验签处理开始");
if (SDKUtil.isEmpty(encoding)) {
encoding = "UTF-8";
}
String certId = resData.get(SDKConstants.param_certId);
log.info("对返回报文串验签使用的验签公钥序列号:[" + certId + "]");
PublicKey verifyKey = CertUtil.getValidatePublicKey(certId);
PublicKey verifyKey = certUtil.getValidatePublicKey(certId);
if(verifyKey == null) {
log.error("未找到此序列号证书。");
return false;
......@@ -110,13 +117,13 @@ public class QrcService {
if (SDKUtil.isEmpty(signType)) {
signType = QRC_SIGNTYPE_SHA1WITHRSA;
}
try {
if (VERSION_1_0_0.equals(version)) {
//被扫脱机码两个接口无视配置固定按sha256withrsa处理。下面两个ifelse别改变顺序。
if (QRC_SIGNTYPE_SHA256WITHRSA.equals(signType)
|| "0420000903".equals(reqType)
|| "0410000903".equals(reqType)) {
|| "0410000903".equals(reqType)) {
boolean result = SDKUtil.verifyRsa2(resData, verifyKey, encoding);
log.info("验签" + (result? "成功":"失败") + "。");
return result;
......@@ -147,7 +154,7 @@ public class QrcService {
public static String encryptPin(String accNo, String pin, String encoding) {
return AcpService.encryptPin(accNo, pin, encoding);
}
/**
* 敏感信息加密并做base64(卡号,手机号,cvn2,有效期)<br>
* @param data 送 phoneNo,cvn2,有效期<br>
......@@ -157,7 +164,7 @@ public class QrcService {
public static String encryptData(String data, String encoding) {
return AcpService.encryptData(data, encoding);
}
/**
* 敏感信息解密,使用配置文件acp_sdk.properties解密<br>
* @param base64EncryptedInfo 加密信息<br>
......@@ -176,19 +183,19 @@ public class QrcService {
* @param encoding<br>
* @return
*/
public static String decryptData(String base64EncryptedInfo, String certPath,
public static String decryptData(String base64EncryptedInfo, String certPath,
String certPwd, String encoding) {
return AcpService.decryptData(base64EncryptedInfo, certPath, certPwd, encoding);
}
/**
* 获取敏感信息加密证书的物理序列号<br>
* @return
*/
public static String getEncryptCertId(){
return CertUtil.getEncryptCert().certId;
public String getEncryptCertId(){
return certUtil.getEncryptCert().certId;
}
/**
* 功能:后台交易提交请求报文并接收同步应答报文<br>
* @param reqData 请求报文<br>
......@@ -199,7 +206,7 @@ public class QrcService {
public static Map<String,String> post(Map<String, String> reqData, String reqUrl,String encoding) {
return AcpService.post(reqData, reqUrl, encoding);
}
/**
* base64({a=b&c=d})
* @param map
......@@ -213,7 +220,7 @@ public class QrcService {
.append(SDKConstants.RIGHT_BRACE).toString();
return Base64.encodeBase64String(info.getBytes(Charset.forName(encoding)));
}
/**
* base64(rsa({a=b&c=d}))
* @param map
......@@ -240,7 +247,7 @@ public class QrcService {
data = data.substring(1, data.length() - 1);
return SDKUtil.parseRespString(data);
}
/**
* base64(rsa({a=b&c=d}))
* 解析返回报文的payerInfo域,敏感信息加密时使用:<br>
......@@ -253,7 +260,7 @@ public class QrcService {
data = data.substring(1, data.length() - 1);
return SDKUtil.parseRespString(data);
}
/**
* base64(rsa({a=b&c=d}))
* 解析返回报文中的payerInfo域,敏感信息加密时使用,多证书方式。<br>
......@@ -261,7 +268,7 @@ public class QrcService {
* @param encoding<br>
* @return
*/
public static Map<String, String> parseKVEncBase64Field(String base64data, String certPath,
public static Map<String, String> parseKVEncBase64Field(String base64data, String certPath,
String certPwd, String encoding){
String data = QrcService.decryptData(base64data, certPath, certPwd, encoding);
data = data.substring(1, data.length() - 1);
......@@ -290,10 +297,10 @@ public class QrcService {
public static String base64Decode(String base64Str, String encoding){
return AcpService.base64Decode(base64Str, encoding);
}
/**
* luhn算法
*
*
* @param number
* @return
*/
......
/**
*
* Licensed Property to China UnionPay Co., Ltd.
*
*
* (C) Copyright of China UnionPay Co., Ltd. 2010
* All Rights Reserved.
*
*
*
* Modification History:
* =============================================================================
* Author Date Description
......@@ -19,6 +19,8 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
......@@ -33,14 +35,16 @@ import java.util.zip.Inflater;
import static com.liquidnet.service.dragon.channel.unionpay.sdk.SDKConstants.*;
/**
*
*
* @ClassName SDKUtil
* @Description acpsdk工具类
* @date 2016-7-22 下午4:06:18
*/
@Slf4j
@Component
public class SDKUtil {
@Autowired
private CertUtil certUtil;
/**
* 全渠道5.0、二维码signType=01用。
* 1. 按ascii排序。【注意不是字母顺序】
......@@ -55,14 +59,14 @@ public class SDKUtil {
* @param encoding
* @return
*/
public static String signRsa(Map<String, String> data, String certPath, String certPwd, String encoding) {
public String signRsa(Map<String, String> data, String certPath, String certPwd, String encoding) {
try{
String stringData = createLinkString(data, true, false, encoding);
log.info("打印排序后待签名请求报文串(交易返回11验证签名失败时可以用来同正确的进行比对):[" + stringData + "]");
byte[] sha1 = SecureUtil.sha1(stringData.getBytes(encoding));
String sha1Hex = byteArrayToHexString(sha1).toLowerCase();
log.info("sha1结果(交易返回11验证签名失败可以用来同正确的进行比对):[" + sha1Hex + "]");
return Base64.encodeBase64String(SecureUtil.getSignature(CertUtil.getSignCertPrivateKeyByStoreMap(certPath, certPwd), sha1Hex.getBytes()));
return Base64.encodeBase64String(SecureUtil.getSignature(certUtil.getSignCertPrivateKeyByStoreMap(certPath, certPwd), sha1Hex.getBytes()));
} catch (Exception e) {
log.error("calcSignRsa Error", e);
return null;
......@@ -83,14 +87,14 @@ public class SDKUtil {
* @param encoding
* @return
*/
public static String signRsa2(Map<String, String> data, String certPath, String certPwd, String encoding) {
public String signRsa2(Map<String, String> data, String certPath, String certPwd, String encoding) {
try {
String stringData = createLinkString(data, true, false, encoding);
log.info("打印排序后待签名请求报文串(交易返回11验证签名失败时可以用来同正确的进行比对):[" + stringData + "]");
byte[] sha256 = SecureUtil.sha256(stringData.getBytes(encoding));
String sha256Hex = byteArrayToHexString(sha256).toLowerCase();
log.info("sha256(交易返回11验证签名失败可以用来同正确的进行比对):[" + sha256Hex + "]");
return Base64.encodeBase64String(SecureUtil.getSignatureSHA256(CertUtil.getSignCertPrivateKeyByStoreMap(certPath, certPwd), sha256Hex.getBytes()));
return Base64.encodeBase64String(SecureUtil.getSignatureSHA256(certUtil.getSignCertPrivateKeyByStoreMap(certPath, certPwd), sha256Hex.getBytes()));
} catch (Exception e) {
log.error("calcSignRsa2 Error", e);
return null;
......@@ -426,15 +430,15 @@ public class SDKUtil {
* @param certType
* @return
*/
public static int updateEncryptCert(String strCert, String certType ) {
public int updateEncryptCert(String strCert, String certType ) {
if (isEmpty(strCert) || isEmpty(certType))
return -1;
if (CERTTYPE_01.equals(certType)) {
// 更新敏感信息加密公钥
return CertUtil.resetEncryptCertPublicKey(strCert);
return certUtil.resetEncryptCertPublicKey(strCert);
} else if (CERTTYPE_02.equals(certType)) {
// 更新pin敏感信息加密公钥
return CertUtil.resetPinEncryptCertPublicKey(strCert);
return certUtil.resetPinEncryptCertPublicKey(strCert);
} else {
log.info("unknown cerType:"+certType);
return -1;
......@@ -449,7 +453,7 @@ public class SDKUtil {
public static Map<String, String> filterBlank(Map<String, String> contentData){
Map<String, String> submitFromData = new HashMap<String, String>();
Set<String> keyset = contentData.keySet();
for(String key : keyset){
String value = contentData.get(key);
if (!isEmpty(value)) {
......@@ -458,10 +462,10 @@ public class SDKUtil {
}
return submitFromData;
}
/**
* 解压缩.
*
*
* @param inputByte
* byte[]数组类型的数据
* @return 解压缩后的数据
......@@ -492,7 +496,7 @@ public class SDKUtil {
/**
* 压缩.
*
*
* @param inputByte
* 需要解压缩的byte[]数组
* @return 压缩后的数据
......@@ -516,10 +520,10 @@ public class SDKUtil {
compresser.end();
return o.toByteArray();
}
/**
* 判断字符串是否为NULL或空
*
*
* @param s
* 待判断的字符串数据
* @return 判断结果 true-是 false-否
......
/**
*
* Licensed Property to China UnionPay Co., Ltd.
*
*
* (C) Copyright of China UnionPay Co., Ltd. 2010
* All Rights Reserved.
*
*
*
* Modification History:
* =============================================================================
* Author Date Description
......@@ -210,7 +210,7 @@ public class SecureUtil {
return null;
}
}
// /**
// * ANSI X9.8格式(不带主账号信息)pinblock
// * @param pin
......@@ -238,29 +238,29 @@ public class SecureUtil {
// return null;
// }
// }
public static byte[] tripleDesEncryptECBPKCS5Padding(byte[] key, byte[] data) {
try {
if(data == null || data.length % 8 != 0)
throw new IllegalArgumentException("data is null or error data length.");
SecretKey sk = getTripleDesKey(key);
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, sk);
return cipher.doFinal(data);
} catch (Exception e) {
log.error("加密失败", e);
return null;
}
}
/**
* 后补0到位数为unitLength的整数倍
* @param value
* @return
* @param value
* @return
*/
public static byte[] rightPadZero(byte[] value, final int unitLength){
if (value.length % unitLength == 0)
......@@ -268,7 +268,7 @@ public class SecureUtil {
int len = (value.length/unitLength + 1) * unitLength;
return Arrays.copyOf(value, len);
}
/**
* 通过byte数组得到SecretKey类型的密钥
* @param key
......@@ -276,12 +276,12 @@ public class SecureUtil {
* @throws IllegalArgumentException
*/
private static SecretKey getTripleDesKey(byte[] key) {
if (key == null || !(key.length== 8||key.length== 16||key.length== 24))
throw new IllegalArgumentException("key is null or error key length.");
byte[] specKey = new byte[24];
try {
switch (key.length) {
case 16:
......
package com.liquidnet.service;
import com.liquidnet.service.dragon.channel.unionpay.sdk.SDKConfig;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author AnJiabin <anjiabin@zhengzai.tv>
* @version V1.0
* @Description: TODO
* @class: TestSdkConfig
* @Package com.liquidnet.service
* @Copyright: LightNet @ Copyright (c) 2021
* @date 2021/11/9 10:57
*/
@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class TestSdkConfig {
@Autowired
private SDKConfig sdkConfig;
@Test
public void pringSdkConfigInfo(){
System.out.println(sdkConfig.getFileTransUrl());
System.out.println(sdkConfig.getSignCertPath());
System.out.println(sdkConfig.getSignCertPwd());
System.out.println(sdkConfig.getSignCertType());
System.out.println(sdkConfig.getEncryptCertPath());
System.out.println(sdkConfig.getMiddleCertPath());
System.out.println(sdkConfig.getRootCertPath());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment