diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SecureUtil.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SecureUtil.java index 3982fdd..edccc34 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SecureUtil.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SecureUtil.java @@ -1,6 +1,6 @@ package com.egzosn.pay.common.util.sign; -import com.egzosn.pay.common.util.sign.SM3.SM3Digest; +import com.egzosn.pay.common.util.sign.sm3.SM3Digest; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -150,6 +150,7 @@ public class SecureUtil { } public static boolean validateSignBySoft256(PublicKey publicKey, byte[] signData, byte[] srcData) throws Exception { + Signature st = Signature.getInstance(BC_PROV_ALGORITHM_SHA256RSA, "BC"); st.initVerify(publicKey); st.update(srcData); diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/MD5.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/MD5.java index 5db35ac..05237fc 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/MD5.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/MD5.java @@ -4,8 +4,8 @@ package com.egzosn.pay.common.util.sign.encrypt; import com.egzosn.pay.common.util.str.StringUtils; import org.apache.commons.codec.digest.DigestUtils; -import java.io.UnsupportedEncodingException; -import java.security.SignatureException; + +import static com.egzosn.pay.common.util.str.StringUtils.getContentBytes; /** * MD5签名工具 @@ -42,20 +42,5 @@ public class MD5 { - /** - * @param content 需要加密串 - * @param charset 字符集 - * @return 加密后的字节数组 - */ - public static byte[] getContentBytes(String content, String charset) { - if (StringUtils.isEmpty(charset)) { - return content.getBytes(); - } - try { - return content.getBytes(charset); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset); - } - } } \ No newline at end of file diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/SHA1.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/SHA1.java new file mode 100644 index 0000000..83167c5 --- /dev/null +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/SHA1.java @@ -0,0 +1,46 @@ +package com.egzosn.pay.common.util.sign.encrypt; + +import com.egzosn.pay.common.util.str.StringUtils; +import org.apache.commons.codec.digest.DigestUtils; + + +/** + * SHA1签名工具 + * @author Actinia + * @email hayesfu@qq.com + * @create 2017 2017/11/27 0027 + */ +public class SHA1 { + + + + /** + * 签名字符串 + * + * @param text 需要签名的字符串 + * @param key 密钥 + * @param input_charset 编码格式 + * @return 签名结果 + */ + public static String sign(String text, String key, String input_charset) { + //拼接key + text = text + key; + return DigestUtils.sha1Hex( StringUtils.getContentBytes(text, input_charset)); + } + + + /** + * 签名字符串 + * + * @param text 需要签名的字符串 + * @param sign 签名结果 + * @param key 密钥 + * @param input_charset 编码格式 + * @return 签名结果 + */ + public static boolean verify(String text, String sign, String key, String input_charset) { + //判断是否一样 + return StringUtils.equals(sign(text, key, input_charset).toUpperCase(), sign.toUpperCase()); + } + +} diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/SHA256.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/SHA256.java index a2ae7f1..e9c3934 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/SHA256.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/encrypt/SHA256.java @@ -1,14 +1,11 @@ -package com.egzosn.pay.common.util.sign.encrypt;/** - * Description: - * author: Fuzx - * date: 2017/11/27 0027 - */ +package com.egzosn.pay.common.util.sign.encrypt; + +import com.egzosn.pay.common.util.str.StringUtils; +import org.apache.commons.codec.digest.DigestUtils; + +/** -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import java.io.UnsupportedEncodingException; -import java.security.MessageDigest; /** * @author Actinia @@ -16,74 +13,34 @@ import java.security.MessageDigest; * @create 2017 2017/11/27 0027 */ public class SHA256 { - //日志 - protected static final Log log = LogFactory.getLog(SHA256.class); /** - * 算法常量: SHA256 - */ - private static final String ALGORITHM_SHA256 = "SHA-256"; - /** - * sha256计算后进行16进制转换 + * 签名字符串 * - * @param data - * 待计算的数据 - * @param encoding - * 编码 - * @return 计算结果 + * @param text 需要签名的字符串 + * @param key 密钥 + * @param input_charset 编码格式 + * @return 签名结果 */ - public static byte[] sha256X16(String data, String encoding) { - byte[] bytes = sha256(data, encoding); - StringBuilder sha256StrBuff = new StringBuilder(); - for (int i = 0; i < bytes.length; i++) { - if (Integer.toHexString(0xFF & bytes[i]).length() == 1) { - sha256StrBuff.append("0").append( - Integer.toHexString(0xFF & bytes[i])); - } else { - sha256StrBuff.append(Integer.toHexString(0xFF & bytes[i])); - } - } - try { - return sha256StrBuff.toString().getBytes(encoding); - } catch (UnsupportedEncodingException e) { - log.error(e.getMessage(), e); - return null; - } + public static String sign(String text, String key, String input_charset) { + //拼接key + text = text + key; + return DigestUtils.sha512Hex( StringUtils.getContentBytes(text, input_charset)); } + + /** - * sha256计算 + * 签名字符串 * - * @param datas - * 待计算的数据 - * @param encoding - * 字符集编码 - * @return + * @param text 需要签名的字符串 + * @param sign 签名结果 + * @param key 密钥 + * @param input_charset 编码格式 + * @return 签名结果 */ - private static byte[] sha256(String datas, String encoding) { - try { - return sha256(datas.getBytes(encoding)); - } catch (UnsupportedEncodingException e) { - log.error("SHA256计算失败", e); - return null; - } - } - /** - * sha256计算. - * - * @param data - * 待计算的数据 - * @return 计算结果 - */ - private static byte[] sha256(byte[] data) { - MessageDigest md = null; - try { - md = MessageDigest.getInstance(ALGORITHM_SHA256); - md.reset(); - md.update(data); - return md.digest(); - } catch (Exception e) { - log.error("SHA256计算失败", e); - return null; - } + public static boolean verify(String text, String sign, String key, String input_charset) { + //判断是否一样 + return StringUtils.equals(sign(text, key, input_charset).toUpperCase(), sign.toUpperCase()); } + } diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/SM3.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/SM3.java similarity index 99% rename from pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/SM3.java rename to pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/SM3.java index f945530..eba799e 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/SM3.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/SM3.java @@ -1,4 +1,4 @@ -package com.egzosn.pay.common.util.sign.SM3; +package com.egzosn.pay.common.util.sign.sm3; public class SM3 { diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/SM3Digest.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/SM3Digest.java similarity index 98% rename from pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/SM3Digest.java rename to pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/SM3Digest.java index f86288e..cfacdd4 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/SM3Digest.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/SM3Digest.java @@ -1,4 +1,4 @@ -package com.egzosn.pay.common.util.sign.SM3; +package com.egzosn.pay.common.util.sign.sm3; public class SM3Digest { diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/Util.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/Util.java similarity index 99% rename from pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/Util.java rename to pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/Util.java index 26a6801..cdbcacb 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/SM3/Util.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/sm3/Util.java @@ -1,4 +1,4 @@ -package com.egzosn.pay.common.util.sign.SM3; +package com.egzosn.pay.common.util.sign.sm3; import java.math.BigInteger; diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/str/StringUtils.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/str/StringUtils.java index a4cae15..8b451a2 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/str/StringUtils.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/str/StringUtils.java @@ -1,5 +1,7 @@ package com.egzosn.pay.common.util.str; +import java.io.UnsupportedEncodingException; + /** * Created by ZaoSheng on 2016/6/4. */ @@ -108,4 +110,20 @@ public class StringUtils { return !StringUtils.isBlank(cs); } + /** + * @param content 需要加密串 + * @param charset 字符集 + * @return 加密后的字节数组 + */ + public static byte[] getContentBytes(String content, String charset) { + if (StringUtils.isEmpty(charset)) { + return content.getBytes(); + } + try { + return content.getBytes(charset); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("转码过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset); + } + } + } diff --git a/pay-java-demo/src/main/resources/acp_sdk.properties b/pay-java-demo/src/main/resources/acp_sdk.properties new file mode 100644 index 0000000..6eca189 --- /dev/null +++ b/pay-java-demo/src/main/resources/acp_sdk.properties @@ -0,0 +1,69 @@ +##############SDK配置文件(证书方式签名)################ +# 说明: +# 1. 使用时请删除后缀的“.证书”,并将此文件复制到src文件夹下替换原来的acp_sdk.properties。 +# 2. 具体配置项请根据注释修改。 +# +################################################ + +##########################入网测试环境交易发送地址(线上测试需要使用生产环境交易请求地址)############################# + +##交易请求地址 +acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do +acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do +acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do +acpsdk.batchTransUrl=https://gateway.test.95516.com/gateway/api/batchTrans.do +acpsdk.fileTransUrl=https://filedownload.test.95516.com/ +acpsdk.appTransUrl=https://gateway.test.95516.com/gateway/api/appTransReq.do +acpsdk.cardTransUrl=https://gateway.test.95516.com/gateway/api/cardTransReq.do + +#以下缴费产品使用,其余产品用不到 +acpsdk.jfFrontTransUrl=https://gateway.test.95516.com/jiaofei/api/frontTransReq.do +acpsdk.jfBackTransUrl=https://gateway.test.95516.com/jiaofei/api/backTransReq.do +acpsdk.jfSingleQueryUrl=https://gateway.test.95516.com/jiaofei/api/queryTrans.do +acpsdk.jfCardTransUrl=https://gateway.test.95516.com/jiaofei/api/cardTransReq.do +acpsdk.jfAppTransUrl=https://gateway.test.95516.com/jiaofei/api/appTransReq.do + +######################################################################## + +# 报文版本号,固定5.1.0,请勿改动 +acpsdk.version=5.1.0 + +# 签名方式,证书方式固定01,请勿改动 +acpsdk.signMethod=01 + +# 是否验证验签证书的CN,测试环境请设置false,生产环境请设置true。非false的值默认都当true处理。 +acpsdk.ifValidateCNName=false + +# 是否验证https证书,测试环境请设置false,生产环境建议优先尝试true,不行再false。非true的值默认都当false处理。 +acpsdk.ifValidateRemoteCert=false + +#后台通知地址,填写接收银联后台通知的地址,必须外网能访问 +#acpsdk.backUrl=http://222.222.222.222:8080/ACPSample_B2C/backRcvResponse +acpsdk.backUrl=http://sailinmu.iok.la:19088/backRcvResponse + +#前台通知地址,填写处理银联前台通知的地址,必须外网能访问 +acpsdk.frontUrl=http://sailinmu.iok.la:19088/frontRcvResponse + +#########################入网测试环境签名证书配置 ################################ +# 多证书的情况证书路径为代码指定,可不对此块做配置。 +# 签名证书路径,必须使用绝对路径,如果不想使用绝对路径,可以自行实现相对路径获取证书的方法;测试证书所有商户共用开发包中的测试签名证书,生产环境请从cfca下载得到。 +# windows样例: +acpsdk.signCert.path=D:/certs/acp_test_sign.pfx +# linux样例(注意:在linux下读取证书需要保证证书有被应用读的权限)(后续其他路径配置也同此条说明) +#acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/acp_test_sign.pfx + +# 签名证书密码,测试环境固定000000,生产环境请修改为从cfca下载的正式证书的密码,正式环境证书密码位数需小于等于6位,否则上传到商户服务网站会失败 +acpsdk.signCert.pwd=000000 +# 签名证书类型,固定不需要修改 +acpsdk.signCert.type=PKCS12 + +##########################加密证书配置################################ +# 敏感信息加密证书路径(商户号开通了商户对敏感信息加密的权限,需要对 卡号accNo,pin和phoneNo,cvn2,expired加密(如果这些上送的话),对敏感信息加密使用) +acpsdk.encryptCert.path=d:/certs/acp_test_enc.cer + +##########################验签证书配置################################ +# 验签中级证书路径(银联提供) +acpsdk.middleCert.path=D:/certs/acp_test_middle.cer +# 验签根证书路径(银联提供) +acpsdk.rootCert.path=D:/certs/acp_test_root.cer + diff --git a/pay-java-union/resource/acp_test_enc.cer b/pay-java-demo/src/main/resources/acp_test_enc.cer similarity index 100% rename from pay-java-union/resource/acp_test_enc.cer rename to pay-java-demo/src/main/resources/acp_test_enc.cer diff --git a/pay-java-union/resource/acp_test_middle.cer b/pay-java-demo/src/main/resources/acp_test_middle.cer similarity index 100% rename from pay-java-union/resource/acp_test_middle.cer rename to pay-java-demo/src/main/resources/acp_test_middle.cer diff --git a/pay-java-union/resource/acp_test_root.cer b/pay-java-demo/src/main/resources/acp_test_root.cer similarity index 100% rename from pay-java-union/resource/acp_test_root.cer rename to pay-java-demo/src/main/resources/acp_test_root.cer diff --git a/pay-java-union/resource/acp_test_sign.pfx b/pay-java-demo/src/main/resources/acp_test_sign.pfx similarity index 100% rename from pay-java-union/resource/acp_test_sign.pfx rename to pay-java-demo/src/main/resources/acp_test_sign.pfx diff --git a/pay-java-union/resource/acp_sdk.properties b/pay-java-union/resource/acp_sdk.properties deleted file mode 100644 index a998100..0000000 --- a/pay-java-union/resource/acp_sdk.properties +++ /dev/null @@ -1,69 +0,0 @@ -##############SDKļ֤鷽ʽǩ################ -# ˵ -# 1. ʹʱɾ׺ġ.֤顱ļƵsrcļ滻ԭacp_sdk.properties -# 2. ע޸ġ -# -################################################ - -##########################Ի׷͵ַϲҪʹַ############################# - -##ַ -acpsdk.frontTransUrl=https://gateway.test.95516.com/gateway/api/frontTransReq.do -acpsdk.backTransUrl=https://gateway.test.95516.com/gateway/api/backTransReq.do -acpsdk.singleQueryUrl=https://gateway.test.95516.com/gateway/api/queryTrans.do -acpsdk.batchTransUrl=https://gateway.test.95516.com/gateway/api/batchTrans.do -acpsdk.fileTransUrl=https://filedownload.test.95516.com/ -acpsdk.appTransUrl=https://gateway.test.95516.com/gateway/api/appTransReq.do -acpsdk.cardTransUrl=https://gateway.test.95516.com/gateway/api/cardTransReq.do - -#½ɷѲƷʹãƷò -acpsdk.jfFrontTransUrl=https://gateway.test.95516.com/jiaofei/api/frontTransReq.do -acpsdk.jfBackTransUrl=https://gateway.test.95516.com/jiaofei/api/backTransReq.do -acpsdk.jfSingleQueryUrl=https://gateway.test.95516.com/jiaofei/api/queryTrans.do -acpsdk.jfCardTransUrl=https://gateway.test.95516.com/jiaofei/api/cardTransReq.do -acpsdk.jfAppTransUrl=https://gateway.test.95516.com/jiaofei/api/appTransReq.do - -######################################################################## - -# İ汾ţ̶5.1.0Ķ -acpsdk.version=5.1.0 - -# ǩʽ֤鷽ʽ̶01Ķ -acpsdk.signMethod=01 - -# Ƿ֤ǩ֤CNԻfalsetruefalseֵĬ϶true -acpsdk.ifValidateCNName=false - -# Ƿ֤https֤飬ԻfalseȳtruefalsetrueֵĬ϶false -acpsdk.ifValidateRemoteCert=false - -#ַ̨֪ͨд̨֪ͨĵַܷ -#acpsdk.backUrl=http://222.222.222.222:8080/ACPSample_B2C/backRcvResponse -acpsdk.backUrl=http://sailinmu.iok.la:19088/backRcvResponse - -#ǰַ̨֪ͨдǰ̨֪ͨĵַܷ -acpsdk.frontUrl=http://sailinmu.iok.la:19088/frontRcvResponse - -#########################Իǩ֤ ################################ -# ֤֤·ΪָɲԴ˿á -# ǩ֤·ʹþ·ʹþ·ʵ·ȡ֤ķ֤̻ÿеIJǩ֤飬cfcaصõ -# windows -acpsdk.signCert.path=D:/certs/acp_test_sign.pfx -# linuxע⣺linux¶ȡ֤Ҫ֤֤бӦöȨޣ·Ҳͬ˵ -#acpsdk.signCert.path=/SERVICE01/usr/ac_frnas/conf/ACPtest/acp_test_sign.pfx - -# ǩ֤룬Ի̶000000޸Ϊcfcaصʽ֤룬ʽ֤λСڵ6λϴ̻վʧ -acpsdk.signCert.pwd=000000 -# ǩ̶֤ͣҪ޸ -acpsdk.signCert.type=PKCS12 - -##########################֤################################ -# Ϣ֤·(̻ſ̻ͨϢܵȨޣҪ accNopinphoneNocvn2expiredܣЩ͵ĻϢʹ) -acpsdk.encryptCert.path=d:/certs/acp_test_enc.cer - -##########################ǩ֤################################ -# ǩм֤·(ṩ) -acpsdk.middleCert.path=D:/certs/acp_test_middle.cer -# ǩ֤·(ṩ) -acpsdk.rootCert.path=D:/certs/acp_test_root.cer - diff --git a/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/CertUtil.java b/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/CertUtil.java index f90c2e4..797db76 100644 --- a/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/CertUtil.java +++ b/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/CertUtil.java @@ -18,7 +18,6 @@ package com.egzosn.pay.union.SDK; import com.egzosn.pay.common.util.str.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.io.*; import java.math.BigInteger; diff --git a/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKConfig.java b/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKConfig.java index f94fa41..7d1a33d 100644 --- a/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKConfig.java +++ b/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKConfig.java @@ -216,7 +216,7 @@ public class SDKConfig { } /** - * 根据传入的 {@link #load(java.util.Properties)}对象设置配置参数 + * 根据传入的 {@link #loadProperties(java.util.Properties)}对象设置配置参数 * * @param pro */ @@ -400,7 +400,7 @@ public class SDKConfig { return SDKConstants.SIGNMETHOD_RSA; case "SHA256": return SDKConstants.SIGNMETHOD_SHA256; - case "SM3": + case "sm3": return SDKConstants.SIGNMETHOD_SM3; default: return SDKConstants.SIGNMETHOD_RSA; diff --git a/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKUtils.java b/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKUtils.java index c8918dc..9cab50c 100644 --- a/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKUtils.java +++ b/pay-java-union/src/main/java/com/egzosn/pay/union/SDK/SDKUtils.java @@ -94,8 +94,8 @@ public class SDKUtils { // 验证签名需要用银联发给商户的公钥证书. boolean result = SecureUtil.validateSignBySoft256(x509Cert .getPublicKey(), Base64.decode(stringSign - ), SHA256.sha256X16( - stringData, encoding)); + ), SHA256.sign( + stringData, "", encoding).getBytes()); log.info("验证签名" + (result? "成功":"失败")); return result; } catch (UnsupportedEncodingException e) { diff --git a/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayConfigStorage.java b/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayConfigStorage.java index 97787b3..a1c8f2e 100644 --- a/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayConfigStorage.java +++ b/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayConfigStorage.java @@ -20,21 +20,9 @@ public class UnionPayConfigStorage extends BasePayConfigStorage { * 商户收款账号 */ public volatile String seller; - //公钥 - private volatile String aliPublicKey; - public String getAliPublicKey () { - return aliPublicKey; - } - - public void setAliPublicKey (String aliPublicKey) { - setKeyPublic(aliPublicKey); - this.aliPublicKey = aliPublicKey; - } - - @Override public String getAppid () { return null;