diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java b/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java index 68aa653..533f248 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/http/UriVariables.java @@ -1,17 +1,9 @@ package com.egzosn.pay.common.http; -import com.alibaba.fastjson.JSON; -import org.apache.http.Consts; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; - import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * URL表达式处理器 @@ -115,7 +107,7 @@ public class UriVariables { continue; } - builder.append(key).append("=").append(URLEncoder.encode((String) pe.get(key), "utf-8")).append("&"); + builder.append(key).append("=").append(URLEncoder.encode( pe.get(key).toString(), "utf-8")).append("&"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } diff --git a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/CertDescriptor.java b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/CertDescriptor.java index cab3c4e..0b640ea 100644 --- a/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/CertDescriptor.java +++ b/pay-java-common/src/main/java/com/egzosn/pay/common/util/sign/CertDescriptor.java @@ -37,9 +37,10 @@ public class CertDescriptor { /** 证书容器,存储对商户请求报文签名私钥证书. */ private KeyStore keyStore = null; - /** 验签中级证书 */ + /** 验签公钥/中级证书 */ private X509Certificate publicKeyCert = null; - + /** 验签根证书 */ + private X509Certificate rootKeyCert = null; @@ -53,7 +54,7 @@ public class CertDescriptor { CertificateFactory cf = null; FileInputStream in = null; try { - cf = CertificateFactory.getInstance("X.509", "BC"); + cf = CertificateFactory.getInstance("X.509"); in = new FileInputStream(path); encryptCertTemp = (X509Certificate) cf.generateCertificate(in); // 打印证书加载信息,供测试阶段调试 @@ -63,9 +64,7 @@ public class CertDescriptor { log.error("InitCert Error", e); } catch (FileNotFoundException e) { log.error("InitCert Error File Not Found", e); - } catch (NoSuchProviderException e) { - log.error("LoadVerifyCert Error No BC Provider", e); - } finally { + }finally { if (null != in) { try { in.close(); @@ -82,7 +81,7 @@ public class CertDescriptor { * * @return */ - public PrivateKey getSignCertPrivateKey() { + public PrivateKey getSignCertPrivateKey(String pwd) { try { Enumeration aliasenum = keyStore.aliases(); String keyAlias = null; @@ -90,7 +89,7 @@ public class CertDescriptor { keyAlias = aliasenum.nextElement(); } PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, - "SDKConfig.getConfig().getSignCertPwd()".toCharArray()); + pwd.toCharArray()); return privateKey; } catch (KeyStoreException e) { log.error("getSignCertPrivateKey Error", e); @@ -171,11 +170,10 @@ public class CertDescriptor { private KeyStore getKeyInfo(String pfxkeyfile, String keypwd, String type) throws IOException { log.warn("加载签名证书==>" + pfxkeyfile); - FileInputStream fis = null; - try { - KeyStore ks = KeyStore.getInstance(type, "BC"); + try(FileInputStream fis = new FileInputStream(pfxkeyfile);) { + KeyStore ks = KeyStore.getInstance(type); log.warn("Load RSA CertPath=[" + pfxkeyfile + "],Pwd=["+ keypwd + "],type=["+type+"]"); - fis = new FileInputStream(pfxkeyfile); + char[] nPassword = null; nPassword = null == keypwd || "".equals(keypwd.trim()) ? null: keypwd.toCharArray(); if (null != ks) { @@ -185,9 +183,6 @@ public class CertDescriptor { } catch (Exception e) { log.error("getKeyInfo Error", e); return null; - } finally { - if(null!=fis) - fis.close(); } } @@ -255,23 +250,43 @@ public class CertDescriptor { } /** - * 用配置文件acp_sdk.properties配置路径 加载敏感信息加密证书 + * 加载中级证书 */ public void initPublicCert(String certPath) { if (!StringUtils.isEmpty(certPath)) { publicKeyCert = initCert(certPath); - log.info("Load MiddleCert Successful"); + log.info("Load PublicKeyCert Successful"); } else { - log.info("WARN: acpsdk.middle.path is empty"); + log.info("PublicKeyCert is empty"); } } /** - * 从配置文件acp_sdk.properties中获取验签公钥使用的中级证书 + * 加载根证书 + */ + public void initRootCert(String certPath) { + if (!StringUtils.isEmpty(certPath)) { + rootKeyCert = initCert(certPath); + log.info("Load RootCert Successful"); + } else { + log.info("RootCert is empty"); + } + } + + /** + * 获取公钥/中级证书 * @return */ public X509Certificate getPublicCert() { return publicKeyCert; } + + /** + * 获取中级证书 + * @return + */ + public X509Certificate getRootCert() { + return rootKeyCert; + } /** 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 e9c3934..b7ed21b 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 @@ -25,7 +25,7 @@ public class SHA256 { public static String sign(String text, String key, String input_charset) { //拼接key text = text + key; - return DigestUtils.sha512Hex( StringUtils.getContentBytes(text, input_charset)); + return DigestUtils.sha256Hex( StringUtils.getContentBytes(text, input_charset)); } diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/PayController.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/PayController.java index 66c3cf0..32c72d6 100644 --- a/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/PayController.java +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/PayController.java @@ -2,6 +2,7 @@ package com.egzosn.pay.demo.controller; +import com.alibaba.fastjson.JSONObject; import com.egzosn.pay.ali.bean.AliTransactionType; import com.egzosn.pay.common.api.Callback; import com.egzosn.pay.common.api.PayConfigStorage; @@ -82,7 +83,7 @@ public class PayController { //获取对应的支付账户操作工具(可根据账户id) PayResponse payResponse = service.getPayResponse(payId); - PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, UUID.randomUUID().toString().replace("-", ""), PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType)); + PayOrder order = new PayOrder("订单title", "摘要", null == price ? new BigDecimal(0.01) : price, "22222222233", PayType.valueOf(payResponse.getStorage().getPayType()).getTransactionType(transactionType)); // ------ 微信H5使用---- order.setSpbillCreateIp(request.getHeader("X-Real-IP")); StringBuffer requestURL = request.getRequestURL(); @@ -309,7 +310,9 @@ public class PayController { PayResponse payResponse = service.getPayResponse(payId); PayConfigStorage storage = payResponse.getStorage(); //获取支付方返回的对应参数 - Map params = payResponse.getService().getParameter2Map(request.getParameterMap(), request.getInputStream()); +// Map params = payResponse.getService().getParameter2Map(request.getParameterMap(), request.getInputStream()); + Map params = JSONObject.parseObject("{\"bizType\":\"000201\",\"signPubKeyCert\":\"-----BEGIN CERTIFICATE-----\\r\\nMIIEQzCCAyugAwIBAgIFEBJJZVgwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UEBhMC\\r\\nQ04xMDAuBgNVBAoTJ0NoaW5hIEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1dGhv\\r\\ncml0eTEXMBUGA1UEAxMOQ0ZDQSBURVNUIE9DQTEwHhcNMTcxMTAxMDcyNDA4WhcN\\r\\nMjAxMTAxMDcyNDA4WjB3MQswCQYDVQQGEwJjbjESMBAGA1UEChMJQ0ZDQSBPQ0Ex\\r\\nMQ4wDAYDVQQLEwVDVVBSQTEUMBIGA1UECxMLRW50ZXJwcmlzZXMxLjAsBgNVBAMU\\r\\nJTA0MUBaMjAxNy0xMS0xQDAwMDQwMDAwOlNJR05AMDAwMDAwMDEwggEiMA0GCSqG\\r\\nSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDDIWO6AESrg+34HgbU9mSpgef0sl6avr1d\\r\\nbD/IjjZYM63SoQi3CZHZUyoyzBKodRzowJrwXmd+hCmdcIfavdvfwi6x+ptJNp9d\\r\\nEtpfEAnJk+4quriQFj1dNiv6uP8ARgn07UMhgdYB7D8aA1j77Yk1ROx7+LFeo7rZ\\r\\nDdde2U1opPxjIqOPqiPno78JMXpFn7LiGPXu75bwY2rYIGEEImnypgiYuW1vo9UO\\r\\nG47NMWTnsIdy68FquPSw5FKp5foL825GNX3oJSZui8d2UDkMLBasf06Jz0JKz5AV\\r\\nblaI+s24/iCfo8r+6WaCs8e6BDkaijJkR/bvRCQeQpbX3V8WoTLVAgMBAAGjgfQw\\r\\ngfEwHwYDVR0jBBgwFoAUz3CdYeudfC6498sCQPcJnf4zdIAwSAYDVR0gBEEwPzA9\\r\\nBghggRyG7yoBATAxMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmNmY2EuY29tLmNu\\r\\nL3VzL3VzLTE0Lmh0bTA5BgNVHR8EMjAwMC6gLKAqhihodHRwOi8vdWNybC5jZmNh\\r\\nLmNvbS5jbi9SU0EvY3JsMjQ4NzIuY3JsMAsGA1UdDwQEAwID6DAdBgNVHQ4EFgQU\\r\\nmQQLyuqYjES7qKO+zOkzEbvdFwgwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUF\\r\\nBwMEMA0GCSqGSIb3DQEBBQUAA4IBAQAujhBuOcuxA+VzoUH84uoFt5aaBM3vGlpW\\r\\nKVMz6BUsLbIpp1ho5h+LaMnxMs6jdXXDh/du8X5SKMaIddiLw7ujZy1LibKy2jYi\\r\\nYYfs3tbZ0ffCKQtv78vCgC+IxUUurALY4w58fRLLdu8u8p9jyRFHsQEwSq+W5+bP\\r\\nMTh2w7cDd9h+6KoCN6AMI1Ly7MxRIhCbNBL9bzaxF9B5GK86ARY7ixkuDCEl4XCF\\r\\nJGxeoye9R46NqZ6AA/k97mJun//gmUjStmb9PUXA59fR5suAB5o/5lBySZ8UXkrI\\r\\npp/iLT8vIl1hNgLh0Ghs7DBSx99I+S3VuUzjHNxL6fGRhlix7Rb8\\r\\n-----END CERTIFICATE-----\",\"orderId\":\"20171213224128\",\"signature\":\"l8xBYSoMNzt01DDa9/JYcrQKWxN5tasUgSxf6NNsQK5t+DqMr2G9qhHXnDg5bEzeRyTFP4bM3htX9RTRhXYDy7EEsL46ZD4ib5I6mp2wXx+26zscUcLdJUiddkY5eFvQK4tPC8blw7Y6p858yiVJpHgbOK3cONhS7vwPJtK2jMbkY+GATu3aZ4iygkQc75cG+EW8nJQVwLNh7q9A6A6II18EFxR7XubdlIHXv/InVaS6ux8Wh2nmQlhRRnLtHq1ri7v1QPlu2FzM+kaf7/fn61iGr8zEPj62NzWDXue62LUfb4kTRgdkcJnfJBJl8vjZ/w93UtsnK3zjzJC/Nu+wCw==\",\"txnSubType\":\"01\",\"traceNo\":\"492156\",\"accNo\":\"6221********0000\",\"settleAmt\":\"1000\",\"settleCurrencyCode\":\"156\",\"settleDate\":\"1213\",\"txnType\":\"01\",\"encoding\":\"UTF-8\",\"version\":\"5.1.0\",\"queryId\":\"511712132241284921568\",\"accessType\":\"0\",\"exchangeRate\":\"0\",\"respMsg\":\"success\",\"traceTime\":\"1213224128\",\"txnTime\":\"20171213224128\",\"merId\":\"777290058154626\",\"currencyCode\":\"156\",\"respCode\":\"00\",\"signMethod\":\"01\",\"txnAmt\":\"1000\"}"); + if (null == params) { return payResponse.getService().getPayOutMessage("fail", "失败").toMessage(); } diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/dao/ApyAccountRepository.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/dao/ApyAccountRepository.java index 4933399..11a42fa 100644 --- a/pay-java-demo/src/main/java/com/egzosn/pay/demo/dao/ApyAccountRepository.java +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/dao/ApyAccountRepository.java @@ -83,19 +83,20 @@ public class ApyAccountRepository { ApyAccount apyAccount4 = new ApyAccount(); apyAccount4.setPayId(4); - apyAccount4.setPartner("777290058110097"); + apyAccount4.setPartner("777290058154626"); // apyAccount4.setAppid("777290058110097"); - apyAccount4.setPublicKey(""); - apyAccount4.setPrivateKey("000000"); - apyAccount4.setNotifyUrl("http://sailinmu.iok.la:19088/backRcvResponse"); + apyAccount4.setPublicKey("D:\\certs\\acp_test_middle.cer;D:\\certs\\acp_test_root.cer"); + apyAccount4.setPrivateKey("D:\\certs\\acp_test_sign.pfx;000000"); + apyAccount4.setNotifyUrl("http://b1234780541.eicp.net/payBack4.json"); // 无需同步回调可不填 app填这个就可以 - apyAccount4.setReturnUrl("http://sailinmu.iok.la:19088/backRcvResponse"); + apyAccount4.setReturnUrl("http://b1234780541.eicp.net/payBack4.json"); apyAccount4.setSeller(""); apyAccount4.setInputCharset("UTF-8"); - apyAccount4.setSignType(SignUtils.RSA.name()); + apyAccount4.setSignType(SignUtils.RSA2.name()); apyAccount4.setPayType(PayType.unionPay); apyAccount4.setMsgType(MsgType.json); - apyAccounts.put(apyAccount4.getPayId(), apyAccount3); + apyAccount4.setTest(true); + apyAccounts.put(apyAccount4.getPayId(), apyAccount4); } //_____________________________________________________________ diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/PayType.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/PayType.java index cf2f078..54c4f67 100644 --- a/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/PayType.java +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/entity/PayType.java @@ -150,6 +150,8 @@ public enum PayType implements BasePayType { @Override public PayService getPayService(ApyAccount apyAccount) { UnionPayConfigStorage unionPayConfigStorage = new UnionPayConfigStorage(); + unionPayConfigStorage.setMerId(apyAccount.getPartner()); + unionPayConfigStorage.setCertSign(true); unionPayConfigStorage.setKeyPublic(apyAccount.getPublicKey()); unionPayConfigStorage.setKeyPrivate(apyAccount.getPrivateKey()); unionPayConfigStorage.setNotifyUrl(apyAccount.getNotifyUrl()); diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/ApyAccountService.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/ApyAccountService.java index 496d52c..d794890 100644 --- a/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/ApyAccountService.java +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/ApyAccountService.java @@ -44,7 +44,7 @@ public class ApyAccountService { */ public PayResponse getPayResponse(Integer id) { - PayResponse payResponse = payResponses.get(id); + PayResponse payResponse = null; if (payResponse == null) { ApyAccount apyAccount = dao.findByPayId(id); if (apyAccount == null) { diff --git a/pay-java-demo/src/main/webapp/dddd.html b/pay-java-demo/src/main/webapp/dddd.html new file mode 100644 index 0000000..62e7a6d --- /dev/null +++ b/pay-java-demo/src/main/webapp/dddd.html @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pay-java-demo/src/main/webapp/sss.html b/pay-java-demo/src/main/webapp/sss.html new file mode 100644 index 0000000..8e7c84e --- /dev/null +++ b/pay-java-demo/src/main/webapp/sss.html @@ -0,0 +1,2 @@ +
+
\ No newline at end of file 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 d79b28a..6117c8d 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 @@ -18,10 +18,7 @@ public class UnionPayConfigStorage extends BasePayConfigStorage { */ private volatile String merId; - /** - * 应用私钥,rsa_private pkcs8格式 生成签名时使用 - */ - private volatile String keyPrivatePwd; + /** * 商户收款账号 @@ -42,9 +39,9 @@ public class UnionPayConfigStorage extends BasePayConfigStorage { super.setKeyPrivate(keyPrivate); if (isCertSign() && keyPrivate.length() < 1024 && keyPrivate.contains(";")){ String[] split = keyPrivate.split(";"); - keyPrivatePwd = split[1]; + setKeyPrivateCertPwd( split[1]); super.setKeyPrivate(split[0]); - getCertDescriptor().initPrivateSignCert(getKeyPrivate(), keyPrivatePwd, "PKCS12"); + getCertDescriptor().initPrivateSignCert(getKeyPrivate(), getKeyPrivateCertPwd(), "PKCS12"); } } @@ -53,7 +50,9 @@ public class UnionPayConfigStorage extends BasePayConfigStorage { public void setKeyPublic(String keyPublic) { super.setKeyPublic(keyPublic); if (isCertSign() && keyPublic.length() < 1024 ){ - getCertDescriptor().initPublicCert(keyPublic); + String[] split = keyPublic.split(";"); + getCertDescriptor().initPublicCert(split[0]); + getCertDescriptor().initRootCert(split[1]); } } diff --git a/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayService.java b/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayService.java index 465b64b..082e2fc 100644 --- a/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayService.java +++ b/pay-java-union/src/main/java/com/egzosn/pay/union/api/UnionPayService.java @@ -10,17 +10,21 @@ import com.egzosn.pay.common.exception.PayErrorException; import com.egzosn.pay.common.http.HttpConfigStorage; import com.egzosn.pay.common.util.MatrixToImageWriter; import com.egzosn.pay.common.util.sign.SignUtils; -import com.egzosn.pay.common.util.sign.encrypt.*; +import com.egzosn.pay.common.util.sign.encrypt.RSA; +import com.egzosn.pay.common.util.sign.encrypt.RSA2; import com.egzosn.pay.common.util.str.StringUtils; -import com.egzosn.pay.union.sdk.SDKConstants; import com.egzosn.pay.union.enums.UnionTransactionType; import com.egzosn.pay.union.request.UnionQueryOrder; +import com.egzosn.pay.union.sdk.SDKConstants; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; import java.io.InputStream; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; +import java.security.cert.*; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; @@ -32,7 +36,7 @@ import java.util.*; */ public class UnionPayService extends BasePayService { //日志 - protected static final Log LOG = LogFactory.getLog(UnionPayService.class); + protected static final Log log = LogFactory.getLog(UnionPayService.class); /** * 测试域名 */ @@ -66,6 +70,7 @@ public class UnionPayService extends BasePayService { public UnionPayService (PayConfigStorage payConfigStorage, HttpConfigStorage configStorage) { super(payConfigStorage, configStorage); + } @@ -83,7 +88,7 @@ public class UnionPayService extends BasePayService { //商户代码 params.put(SDKConstants.param_merId, payConfigStorage.getPid()); - DateFormat df = new SimpleDateFormat("YYYYMMDDhhmmss"); + DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); //订单发送时间 params.put(SDKConstants.param_txnTime, df.format(System.currentTimeMillis())); // 订单超时时间。 @@ -126,7 +131,6 @@ public class UnionPayService extends BasePayService { // 校验失败 } }else{ - } return false; } @@ -214,13 +218,13 @@ public class UnionPayService extends BasePayService { parameters.put(SDKConstants.param_signMethod, SDKConstants.SIGNMETHOD_RSA); parameters.put(SDKConstants.param_certId, payConfigStorage.getCertDescriptor().getSignCertId()); signStr = SignUtils.SHA1.createSign( SignUtils.parameterText(parameters, "&", "signature"),"", payConfigStorage.getInputCharset()); - parameters.put(SDKConstants.param_signature, RSA.sign(signStr, payConfigStorage.getCertDescriptor().getSignCertPrivateKey(), payConfigStorage.getInputCharset())); + parameters.put(SDKConstants.param_signature, RSA.sign(signStr, payConfigStorage.getCertDescriptor().getSignCertPrivateKey(payConfigStorage.getKeyPrivateCertPwd()), payConfigStorage.getInputCharset())); break; case RSA2: parameters.put(SDKConstants.param_signMethod, SDKConstants.SIGNMETHOD_RSA); parameters.put(SDKConstants.param_certId, payConfigStorage.getCertDescriptor().getSignCertId()); signStr = SignUtils.SHA256.createSign( SignUtils.parameterText(parameters, "&", "signature"),"", payConfigStorage.getInputCharset()); - parameters.put(SDKConstants.param_signature, RSA2.sign(signStr, payConfigStorage.getCertDescriptor().getSignCertPrivateKey(), payConfigStorage.getInputCharset())); + parameters.put(SDKConstants.param_signature, RSA2.sign(signStr, payConfigStorage.getCertDescriptor().getSignCertPrivateKey(payConfigStorage.getKeyPrivateCertPwd()), payConfigStorage.getInputCharset())); break; case SHA1: case SHA256: @@ -254,7 +258,11 @@ public class UnionPayService extends BasePayService { return RSA.verify(data, stringSign, payConfigStorage.getCertDescriptor().getPublicCert().getPublicKey(), payConfigStorage.getInputCharset()); case RSA2: data = SignUtils.SHA256.createSign(data,"", payConfigStorage.getInputCharset()); - return RSA2.verify(data, stringSign, payConfigStorage.getCertDescriptor().getPublicCert().getPublicKey(), payConfigStorage.getInputCharset()); + X509Certificate cert = genCertificateByStr(resData.get(SDKConstants.param_signPubKeyCert).toString()); + /*验证证书链*/ + verifyCertificate(cert); + return RSA2.verify(data, stringSign,cert.getPublicKey(), payConfigStorage.getInputCharset()); +// return RSA2.verify(data, stringSign, payConfigStorage.getCertDescriptor().getPublicCert().getPublicKey(), payConfigStorage.getInputCharset()); case SHA1: case SHA256: case SM3: @@ -265,6 +273,50 @@ public class UnionPayService extends BasePayService { } } + /** + * 验证证书链 + * @param cert + */ + private void verifyCertificate (X509Certificate cert) { + try { + cert.checkValidity();//验证有效期 + X509Certificate middleCert = payConfigStorage.getCertDescriptor().getPublicCert(); + X509Certificate rootCert = payConfigStorage.getCertDescriptor().getRootCert(); + + X509CertSelector selector = new X509CertSelector(); + selector.setCertificate(cert); + + Set trustAnchors = new HashSet(); + trustAnchors.add(new TrustAnchor(rootCert, null)); + PKIXBuilderParameters pkixParams = new PKIXBuilderParameters( + trustAnchors, selector); + + Set intermediateCerts = new HashSet(); + intermediateCerts.add(rootCert); + intermediateCerts.add(middleCert); + intermediateCerts.add(cert); + + pkixParams.setRevocationEnabled(false); + + CertStore intermediateCertStore = CertStore.getInstance("Collection", + new CollectionCertStoreParameters(intermediateCerts)); + pkixParams.addCertStore(intermediateCertStore); + + CertPathBuilder builder = CertPathBuilder.getInstance("PKIX"); + + @SuppressWarnings("unused") + PKIXCertPathBuilderResult result = (PKIXCertPathBuilderResult) builder + .build(pkixParams); + } catch (java.security.cert.CertPathBuilderException e) { + log.error("verify certificate chain fail.", e); + } catch (CertificateExpiredException e) { + log.error(e); + } catch (CertificateNotYetValidException e) { + log.error(e); + } catch (Exception e) { + log.error(e); + } + } /** * 获取输出二维码,用户返回给支付端, * @@ -368,6 +420,24 @@ public class UnionPayService extends BasePayService { throw new PayErrorException(new PayException("1000", "验证签名失败", response.toJSONString())); } } + /** + * 将字符串转换为X509Certificate对象. + * + * @param x509CertString + * @return + */ + public static X509Certificate genCertificateByStr(String x509CertString) { + X509Certificate x509Cert = null; + try { + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + InputStream tIn = new ByteArrayInputStream( + x509CertString.getBytes("ISO-8859-1")); + x509Cert = (X509Certificate) cf.generateCertificate(tIn); + } catch (Exception e) { + log.error("gen certificate error", e); + } + return x509Cert; + } /** * 将请求参数或者请求流转化为 Map @@ -378,7 +448,30 @@ public class UnionPayService extends BasePayService { */ @Override public Map getParameter2Map (Map parameterMap, InputStream is) { - return null; + + Map params = new TreeMap(); + for (Iterator iter = parameterMap.keySet().iterator(); iter.hasNext();) { + String name = (String) iter.next(); + String[] values = parameterMap.get(name); + String valueStr = ""; + for (int i = 0,len = values.length; i < len; i++) { + valueStr += (i == len - 1) ? values[i] + : values[i] + ","; + } + //乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 + //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); + if (!valueStr.matches("\\w+")){ + try { + if(valueStr.equals(new String(valueStr.getBytes("iso8859-1"), "iso8859-1"))){ + valueStr=new String(valueStr.getBytes("iso8859-1"), payConfigStorage.getInputCharset()); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + params.put(name, valueStr); + } + return params; } /** @@ -415,7 +508,28 @@ public class UnionPayService extends BasePayService { */ @Override public String buildRequest (Map orderInfo, MethodType method) { - return null; + StringBuffer sf = new StringBuffer(); + sf.append(""); + sf.append("
"); + if (null != orderInfo && 0 != orderInfo.size()) { + Set> set = orderInfo.entrySet(); + Iterator> it = set.iterator(); + while (it.hasNext()) { + Map.Entry ey = it.next(); + String key = ey.getKey(); + Object value = ey.getValue(); + sf.append(""); + } + } + sf.append(""); + sf.append(""); + sf.append(""); + sf.append(""); + return sf.toString(); } @@ -542,6 +656,22 @@ public class UnionPayService extends BasePayService { } } + /** + * 将parameterMap对应的key存放至params + * @param parameterMap 请求参数 + * @param params 转化的对象 + * @param key 需要取值的key + * @return params + */ + public Map conversion(Map parameterMap, Map params ,String key){ + String[] values = parameterMap.get(key); + String valueStr = ""; + for (int i = 0,len = values.length; i < len; i++) { + valueStr += (i == len - 1) ? values[i] : values[i] + ","; + } + params.put(key, valueStr); + return params; + } /** * 下载对账单 * @@ -569,10 +699,10 @@ public class UnionPayService extends BasePayService { return null; } -// public String getFrontTransUrl () { -// return payConfigStorage.isTest() ? String.format(FRONT_TRANS_URL,TEST_BASE_DOMAIN):String.format(FRONT_TRANS_URL,RELEASE_BASE_DOMAIN); -// } -// + public String getFrontTransUrl () { + return String.format(FRONT_TRANS_URL,payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN); + } + public String getBackTransUrl () { return String.format(BACK_TRANS_URL, payConfigStorage.isTest() ? TEST_BASE_DOMAIN : RELEASE_BASE_DOMAIN); }