skyfffire 1 долоо хоног өмнө
parent
commit
c2bd26db8a

+ 2 - 1
src/main/java/common/utils/tl/AllinpaySDK.java

@@ -7,6 +7,7 @@ import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import com.jfinal.kit.HttpKit;
 import com.jfinal.kit.StrKit;
+import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
 import java.util.*;
 import java.util.Base64;
@@ -227,7 +228,7 @@ public class AllinpaySDK {
             if (!first) {
                 formData.append("&");
             }
-            formData.append(entry.getKey()).append("=").append(entry.getValue());
+            formData.append(entry.getKey()).append("=").append(URLEncoder.encode(entry.getValue(), "UTF-8"));
             first = false;
         }
         

+ 124 - 0
src/main/java/common/utils/tl/HttpConnectionUtil.java

@@ -0,0 +1,124 @@
+package common.utils.tl;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLEncoder;
+import java.util.Map;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLSession;
+
+import org.apache.commons.logging.Log;
+
+public class HttpConnectionUtil {
+    private HttpURLConnection conn;
+    private String connectUrl;
+
+    public HttpConnectionUtil(String connectUrl) {
+        this.connectUrl = connectUrl;
+    }
+
+    public void init() throws Exception {
+        URL url = new URL(connectUrl);
+        System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
+        HostnameVerifier hv = new HostnameVerifier() {
+            public boolean verify(String urlHostName, SSLSession session) {
+                return urlHostName.equals(session.getPeerHost());
+            }
+        };
+        HttpsURLConnection.setDefaultHostnameVerifier(hv);
+        URLConnection conn = url.openConnection();
+        conn.setDoInput(true);
+        conn.setDoOutput(true);
+        conn.setReadTimeout(60000);
+        conn.setConnectTimeout(30000);
+        if (conn instanceof HttpsURLConnection) {
+            HttpsURLConnection httpsConn = (HttpsURLConnection) conn;
+            httpsConn.setSSLSocketFactory(SSLUtil.getInstance().getSSLSocketFactory());
+        } else if (conn instanceof HttpURLConnection) {
+            HttpURLConnection httpConn = (HttpURLConnection) conn;
+        } else {
+            throw new Exception("不是http/https协议的url");
+        }
+        this.conn = (HttpURLConnection) conn;
+        initDefaultPost();
+    }
+
+    public void destory() {
+        try {
+            if (this.conn != null) {
+                this.conn.disconnect();
+            }
+        } catch (Exception e) {
+
+        }
+    }
+
+    private void initDefaultPost() throws Exception {
+        conn.setDoOutput(true);
+        conn.setDoInput(true);
+        conn.setRequestMethod("POST");
+        conn.setUseCaches(false);
+        conn.setInstanceFollowRedirects(true);
+        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
+    }
+
+    public byte[] postParams(Map<String, String> params, boolean readreturn) throws IOException {
+        StringBuilder outBuf = new StringBuilder();
+        boolean isNotFirst = false;
+        for (Map.Entry<String, String> entry : params.entrySet()) {
+            if (isNotFirst)
+                outBuf.append('&');
+            isNotFirst = true;
+            outBuf
+                    .append(entry.getKey())
+                    .append('=')
+                    .append(URLEncoder.encode(entry.getValue(), "UTF-8"));
+        }
+        System.out.println("参数:" + outBuf.toString());
+        return postParams(outBuf.toString(), readreturn);
+    }
+
+    public byte[] postParams(String message, boolean readreturn) throws IOException {
+        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
+        out.write(message.getBytes("UTF-8"));
+        out.close();
+        if (readreturn) {
+            return readBytesFromStream(conn.getInputStream());
+        } else {
+            return null;
+        }
+    }
+
+    public byte[] postParams(byte[] message, boolean readreturn) throws IOException {
+        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
+        out.write(message);
+        out.close();
+        if (readreturn) {
+            return readBytesFromStream(conn.getInputStream());
+        } else {
+            return null;
+        }
+    }
+
+    private byte[] readBytesFromStream(InputStream is) throws IOException {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        int readLen;
+        byte[] tmpBuf = new byte[4096];
+        while ((readLen = is.read(tmpBuf)) > 0)
+            baos.write(tmpBuf, 0, readLen);
+        is.close();
+        return baos.toByteArray();
+    }
+
+    public HttpURLConnection getConn() {
+        return conn;
+    }
+
+}

+ 59 - 0
src/main/java/common/utils/tl/SSLUtil.java

@@ -0,0 +1,59 @@
+package common.utils.tl;
+
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * SSL管理助手类
+ *
+ * @author Administrator
+ *
+ */
+public class SSLUtil implements X509TrustManager {
+    private SSLSocketFactory sslFactory = null;
+
+    private SSLUtil() {
+    }
+
+    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
+            throws CertificateException {
+    }
+
+    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
+            throws CertificateException {
+    }
+
+    public X509Certificate[] getAcceptedIssuers() {
+        return null;
+    }
+
+    /**
+     * 获取SSL Socket工厂
+     */
+    public SSLSocketFactory getSSLSocketFactory() {
+        return sslFactory;
+    }
+
+    private static SSLUtil _instance = null;
+
+    /**
+     * 获取SSL管理助手类实例
+     */
+    synchronized public static SSLUtil getInstance() throws NoSuchAlgorithmException, KeyManagementException {
+        if (_instance == null) {
+            _instance = new SSLUtil();
+            SSLContext sc = SSLContext.getInstance("SSLv3");
+            sc.init(null, new TrustManager[]{new SSLUtil()}, null);
+            _instance.sslFactory = sc.getSocketFactory();
+        }
+        return _instance;
+    }
+
+}

+ 152 - 0
src/main/java/common/utils/tl/SmUtil.java

@@ -0,0 +1,152 @@
+package common.utils.tl;
+
+import java.io.IOException;
+import java.math.BigInteger;
+import java.security.KeyFactory;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.Signature;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Arrays;
+
+import org.apache.commons.codec.binary.Base64;
+import org.bouncycastle.asn1.ASN1EncodableVector;
+import org.bouncycastle.asn1.ASN1Integer;
+import org.bouncycastle.asn1.ASN1Sequence;
+import org.bouncycastle.asn1.DERSequence;
+import org.bouncycastle.jcajce.spec.SM2ParameterSpec;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.util.encoders.Hex;
+
+public class SmUtil {
+    static {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    /**
+     * 算法常量:SM3withSM2
+     */
+    public static final String ALGORITHM_SM3SM2_BCPROV = "SM3withSM2";
+    private final static int SM3withSM2_RS_LEN = 32;
+
+    public static void main(String[] args) throws Exception {
+        /**商户平台分配的appid,也是签名的certid**/
+        String appid = "00000156";
+        /**商户sm2私钥,用于向通联发起请求前进行签名**/
+        String cusPrivateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgjj4Rk+b0YjwO+UwXofnHf4bK+kaaY5Btkd8nMP2VimmgCgYIKoEcz1UBgi2hRANCAAQqlALW4qGC3bP1x3wo5QsKxaCMEZJ2ODTTwOQ+d8UGU7GoK/y/WMBQWf5upMnFU06p5FxGooXYYoBtldgm03hq";
+        /**商户sm2公钥,需要配置到通联商户平台**/
+        String cusPubKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEKpQC1uKhgt2z9cd8KOULCsWgjBGSdjg008DkPnfFBlOxqCv8v1jAUFn+bqTJxVNOqeRcRqKF2GKAbZXYJtN4ag==";
+
+        /**通联平台sm2公钥,用于请求返回或者通联通知的验签**/
+        String tlPubKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/BnA8BawehBtH0ksPyayo4pmzL/u1FQ2sZcqwOp6bjVqQX4tjo930QAvHZPJ2eez8sCz/RYghcqv4LvMq+kloQ==";
+
+        String blankStr = "请求待签名数据";
+        PrivateKey privkey = privKeySM2FromBase64Str(cusPrivateKey);
+        String sign = signSM3SM2RetBase64(privkey, appid, blankStr.getBytes("UTF-8"));//签名
+        System.out.println(sign);
+
+        String rspBlankStr = "返回待验签数据";//通联返回的明文
+        String rspSign = "AovBKQGUe0xuJ0ox7FgIIX+yB3DzbudgUsnNvJmDV0IdHZtU2Y8vdeUY1pd2vmPUf08hNgdkoz+4WP/D/ktOcA==";//通联返回的签名
+        PublicKey publicKey = pubKeySM2FromBase64Str(tlPubKey);
+        boolean isOk = verifySM3SM2(publicKey, "Allinpay", Base64.decodeBase64(rspSign), rspBlankStr.getBytes("UTF-8"));
+        System.out.println("验签结果:" + isOk);
+
+
+    }
+
+    /**
+     * 签名并BASE64编码-SM3WithSM2
+     */
+    public static String signSM3SM2RetBase64(final PrivateKey privateKey, String certid, final byte[] data) throws Exception {
+        return Base64.encodeBase64String(signSM3SM2(privateKey, certid, data));
+    }
+
+    /**
+     * 签名-SM3WithSM2
+     */
+    public static byte[] signSM3SM2(final PrivateKey privateKey, String certid, final byte[] data) throws Exception {
+        SM2ParameterSpec parameterSpec = new SM2ParameterSpec(certid.getBytes());
+        Signature signer = Signature.getInstance(ALGORITHM_SM3SM2_BCPROV, "BC");
+        signer.setParameter(parameterSpec);
+        signer.initSign(privateKey, new SecureRandom());
+        signer.update(data);
+        return byteAsn12BytePlain(signer.sign());
+    }
+
+    /**
+     * 验证签名-SM3WithSM2
+     */
+    public static boolean verifySM3SM2(final PublicKey publicKey, String certid, final byte[] signData, final byte[] srcData) throws Exception {
+        SM2ParameterSpec parameterSpec = new SM2ParameterSpec(certid.getBytes());
+        Signature verifier = Signature.getInstance(ALGORITHM_SM3SM2_BCPROV, "BC");
+        verifier.setParameter(parameterSpec);
+        verifier.initVerify(publicKey);
+        verifier.update(srcData);
+        return verifier.verify(bytePlain2ByteAsn1(signData));
+    }
+
+    /**
+     * 从字符串读取私钥-目前支持PKCS8(keystr为BASE64格式)
+     */
+    public static PrivateKey privKeySM2FromBase64Str(String keystr) throws Exception {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC");
+        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(keystr)));
+    }
+
+    /**
+     * 从字符串读取RSA公钥(keystr为BASE64格式)
+     */
+    public static PublicKey pubKeySM2FromBase64Str(String keystr) throws Exception {
+        KeyFactory keyFactory = KeyFactory.getInstance("EC");
+        return keyFactory.generatePublic(new X509EncodedKeySpec(Base64.decodeBase64(keystr)));
+    }
+
+    /**
+     * 将普通字节数组转换为ASN1字节数组 适用于SM3withSM2验签时验签明文转换
+     */
+    private static byte[] bytePlain2ByteAsn1(byte[] data) {
+        if (data.length != SM3withSM2_RS_LEN * 2) throw new RuntimeException("err data. ");
+        BigInteger r = new BigInteger(1, Arrays.copyOfRange(data, 0, SM3withSM2_RS_LEN));
+        BigInteger s = new BigInteger(1, Arrays.copyOfRange(data, SM3withSM2_RS_LEN, SM3withSM2_RS_LEN * 2));
+        ASN1EncodableVector v = new ASN1EncodableVector();
+        v.add(new ASN1Integer(r));
+        v.add(new ASN1Integer(s));
+        try {
+            return new DERSequence(v).getEncoded("DER");
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 将ASN1字节数组转换为普通字节数组 适用于SM3withSM2签名时签名结果转换
+     */
+    private static byte[] byteAsn12BytePlain(byte[] dataAsn1) {
+        ASN1Sequence seq = ASN1Sequence.getInstance(dataAsn1);
+        byte[] r = bigIntToFixexLengthBytes(ASN1Integer.getInstance(seq.getObjectAt(0)).getValue());
+        byte[] s = bigIntToFixexLengthBytes(ASN1Integer.getInstance(seq.getObjectAt(1)).getValue());
+        byte[] result = new byte[SM3withSM2_RS_LEN * 2];
+        System.arraycopy(r, 0, result, 0, r.length);
+        System.arraycopy(s, 0, result, SM3withSM2_RS_LEN, s.length);
+        return result;
+    }
+
+    private static byte[] bigIntToFixexLengthBytes(BigInteger rOrS) {
+        byte[] rs = rOrS.toByteArray();
+        if (rs.length == SM3withSM2_RS_LEN) return rs;
+        else if (rs.length == SM3withSM2_RS_LEN + 1 && rs[0] == 0)
+            return Arrays.copyOfRange(rs, 1, SM3withSM2_RS_LEN + 1);
+        else if (rs.length < SM3withSM2_RS_LEN) {
+            byte[] result = new byte[SM3withSM2_RS_LEN];
+            Arrays.fill(result, (byte) 0);
+            System.arraycopy(rs, 0, result, SM3withSM2_RS_LEN - rs.length, rs.length);
+            return result;
+        } else {
+            throw new RuntimeException("err rs: " + Hex.toHexString(rs));
+        }
+    }
+
+}

+ 41 - 0
src/main/java/common/utils/tl/SybConstants.java

@@ -0,0 +1,41 @@
+package common.utils.tl;
+
+public class SybConstants {
+//	测试环境测试参数
+//	public static final String SYB_ORGID = "";//集团/机构模式下该参数不为空,且appid与key是与次参数对应
+//	public static final String SYB_CUSID = "990581007426001";
+//	public static final String SYB_APPID = "00000051";
+//	public static final String SYB_MD5_APPKEY = "allinpay888";
+//	public static final String SYB_APIURL = "http://172.16.1.10/apiweb";
+    /**
+     * 商户RSA私钥,用于向通联发起请求前进行签名
+     **/
+//	public static final String SYB_RSACUSPRIKEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAK5aIo+E1eyWwEIgMB8ZEZRAaWjSAglmfKVhzy8N1eLjAlqPjJgOCqXGEYt/r61AyIjCCJiYVDTHzcqstmbBU7HKpYjTsquCLjRWcL/fhMwMGBSg2bP5mqw5locSOz1gtRujmd3kZo9OIJuWtfG2+wgPPdKUdGZS+5K8WtWCF4z1AgMBAAECgYAPvvqvkPzb9tpqrmsCJ/qvM6kBazP9Ytjfe8ehFYQLT1qrUJsPMXdzNMHpYhD82eSyeymZFGrIcIIMq4/2lD+pYOMQTMGGjoVb2wnQhZFqPdgjXgOQ90E43X69jD3p5F8CuKVNa13I4l3iyfzlVIL780JPdJdug7yKEFdSeOQZUQJBAONlFpIqz87pbnwzfgO5kRTbbI7DcyObb8OEeCK3VlGB3r9P4NoMEDaXm+HnIdv53gnFq+xgbREWUt2nFq9dSUUCQQDESOIdSvIBc3KQTYR+cnlQTH0SOvm0Tlx4KekBCLxTFAFyBqnOBLdVyQb6Z1wxGz855AjnNbHy1rFhUYQ6hPfxAkAIRZUcnBITJMqwGe9rk0SDzbeVOebmVLEsG5WDLcgmDuNbcjxrsiSk178D6LSCnARHtrkaUCenh3hcN8fLeUlBAkABNP2G9pYEYkRbFM7yxBtw3feK7Cfq7uxspL1VD0uxKxdTLy1OIgNKmMDdO1N6zdMWtQtE+LSObLmMgqbQgU7RAkBFX5kl4+B3k+/aCYB/ndqd1nQIr4SNAtLFJDtlW2xah9W2lQL/7KQDT4o4dUMY51m7Bu61SAmKtralv7Hf25yf";
+//	/**通联平台RSA公钥,用于请求返回或者通联通知的验签**/
+//	public static final String SYB_RSATLPUBKEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYXfu4b7xgDSmEGQpQ8Sn3RzFgl5CE4gL4TbYrND4FtCYOrvbgLijkdFgIrVVWi2hUW4K0PwBsmlYhXcbR+JSmqv9zviVXZiym0lK3glJGVCN86r9EPvNTusZZPm40TOEKMVENSYaUjCxZ7JzeZDfQ4WCeQQr2xirqn6LdJjpZ5wIDAQAB";
+//
+//	/**商户sm2私钥,用于向通联发起请求前进行签名**/
+//	public static final String SYB_SM2PPRIVATEKEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgjj4Rk+b0YjwO+UwXofnHf4bK+kaaY5Btkd8nMP2VimmgCgYIKoEcz1UBgi2hRANCAAQqlALW4qGC3bP1x3wo5QsKxaCMEZJ2ODTTwOQ+d8UGU7GoK/y/WMBQWf5upMnFU06p5FxGooXYYoBtldgm03hq";
+//	/**通联平台sm2公钥,用于请求返回或者通联通知的验签**/
+//	public static final String SYB_SM2TLPUBKEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE/BnA8BawehBtH0ksPyayo4pmzL/u1FQ2sZcqwOp6bjVqQX4tjo930QAvHZPJ2eez8sCz/RYghcqv4LvMq+kloQ==";
+
+//	正式环境测试参数
+    public static final String SYB_ORGID = "";//集团/机构模式下该参数不为空,且appid与key是与次参数对应
+    public static final String SYB_CUSID = "990440148166000";
+    public static final String SYB_APPID = "00000003";
+    public static final String SYB_MD5_APPKEY = "a0ea3fa20dbd7bb4d5abf1d59d63bae8";
+    public static final String SYB_APIURL = "https://vsp.allinpay.com/apiweb";//生产环境
+    public static final String SYB_RSACUSPRIKEY = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAO0HpPUP+eHk//Ba6ZOePvoZVDpOCRtt943oeVfCTllye43bqja1jVIaebX0MgX+yPYnWIQIOJ9ubSH0R4iyY9y1/HR00qkUpfW3/0usBPt9qn7r0xtFHerhVCd4dT2rKb2Oc5IhKOg05cw/BmMFohMkFsqt0jlrUXI8zJOlLIcxAgMBAAECgYA9lt/pAYa3iK5sQOMyhUrt54j4QXCiXPeXOxHUmNuM6G9sU+itoI0hCVoYymP5JNQJCf45CH3WB3Z5/SRdQ6Uoo1cjao6cCohPLxMSfJglsZCHckPH53o25RKEza4njIgKC+yN7HAhanKymhw/yYQ6i0aXq38zFIk8djMtE7R6xQJBAP6jvNy7UhPKO5rxGFKR+MvvbO3qnYH6x0jZCGY3FlxuGfbavueOiFtMeK67FuDv683dcUKi+M48yR4kH5CfIusCQQDuS9KF6mlm3kHAiZWgVhE8VVNYGpRLCRDgAKm4InGmvk5mUv+O1yAtAFVAEHWIgD4awC7Eqf1YFrSF/It9HV9TAkEAsXiU7JJxhfFw0XAvL30lFZ1tIfReinSp6A+7VuIV552k4vNaEjC4wEjv43fpXiRZCEXJ5lOHbNXYpfUvOrBuuQJAOpow8rf8Jc0g1G3Be0XPRUwii/c1YuKe4Meo9VybIIuKkkV1Dba/9fEwBepGTURkgYWjur+nSyOCT7UUxLcVewJAPLig8dVfKpsiNwYuveEYMcFaO5xoRuiB7v+CMmvxpuuK+rrFS+d7RdmwDbnBiDV4JkTgFObUiGvB7MtS+LGfhw==";
+    public static final String SYB_RSATLPUBKEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCm9OV6zH5DYH/ZnAVYHscEELdCNfNTHGuBv1nYYEY9FrOzE0/4kLl9f7Y9dkWHlc2ocDwbrFSm0Vqz0q2rJPxXUYBCQl5yW3jzuKSXif7q1yOwkFVtJXvuhf5WRy+1X5FOFoMvS7538No0RpnLzmNi3ktmiqmhpcY/1pmt20FHQQIDAQAB";
+
+    public static final String VERSION = "12";
+    public static final String RET_URL = "https://test.allinpaygd.com/JWeb/reccomparams.jsp";
+    public static final String NOTFIY_URL = "https://test.allinpaygd.com/JWeb/NotifyServlet";
+    public static final String VALID_TIME = "5";
+    public static final String SIGN_TYPE = "SM2";//
+    //	/**商户sm2私钥,用于向通联发起请求前进行签名**/
+    public static final String SYB_SM2PPRIVATEKEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgjj4Rk+b0YjwO+UwXofnHf4bK+kaaY5Btkd8nMP2VimmgCgYIKoEcz1UBgi2hRANCAAQqlALW4qGC3bP1x3wo5QsKxaCMEZJ2ODTTwOQ+d8UGU7GoK/y/WMBQWf5upMnFU06p5FxGooXYYoBtldgm03hq";
+    //	/**通联平台sm2公钥,用于请求返回或者通联通知的验签**/
+    public static final String SYB_SM2TLPUBKEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBQicgWm0KAMqhO3bdqMUEDrKQvYg8cCXHhdGwq7CGE6oJDzJ1P/94HpuVdBf1KidmPxr7HOH+0DAnpeCcx9TcQ==";
+
+}

+ 124 - 0
src/main/java/common/utils/tl/SybPayService.java

@@ -0,0 +1,124 @@
+package common.utils.tl;
+
+import java.net.URLEncoder;
+import java.util.Map;
+import java.util.TreeMap;
+
+public class SybPayService {
+
+    public Map<String, String> cancel(long trxamt, String reqsn, String oldtrxid, String oldreqsn) throws Exception {
+        HttpConnectionUtil http = new HttpConnectionUtil(SybConstants.SYB_APIURL + "/unitorder/cancel");
+        http.init();
+        TreeMap<String, String> params = new TreeMap<String, String>();
+        if (!SybUtil.isEmpty(SybConstants.SYB_ORGID))
+            params.put("orgid", SybConstants.SYB_ORGID);
+        params.put("cusid", SybConstants.SYB_CUSID);
+        params.put("appid", SybConstants.SYB_APPID);
+        params.put("version", "11");
+        params.put("trxamt", String.valueOf(trxamt));
+        params.put("reqsn", reqsn);
+        params.put("oldtrxid", oldtrxid);
+        params.put("oldreqsn", oldreqsn);
+        params.put("randomstr", SybUtil.getValidatecode(8));
+        params.put("signtype", SybConstants.SIGN_TYPE);
+        String appkey = "";
+        if (SybConstants.SIGN_TYPE.equals("RSA"))
+            appkey = SybConstants.SYB_RSACUSPRIKEY;
+        else if (SybConstants.SIGN_TYPE.equals("SM2"))
+            appkey = SybConstants.SYB_SM2PPRIVATEKEY;
+        else
+            appkey = SybConstants.SYB_MD5_APPKEY;
+        params.put("sign", SybUtil.unionSign(params, appkey, SybConstants.SIGN_TYPE));
+        byte[] bys = http.postParams(params, true);
+        String result = new String(bys, "UTF-8");
+        Map<String, String> map = handleResult(result);
+        return map;
+    }
+
+    public Map<String, String> refund(long trxamt, String reqsn, String oldtrxid, String oldreqsn) throws Exception {
+        HttpConnectionUtil http = new HttpConnectionUtil(SybConstants.SYB_APIURL + "/unitorder/refund");
+        http.init();
+        TreeMap<String, String> params = new TreeMap<String, String>();
+        if (!SybUtil.isEmpty(SybConstants.SYB_ORGID))
+            params.put("orgid", SybConstants.SYB_ORGID);
+        params.put("cusid", SybConstants.SYB_CUSID);
+        params.put("appid", SybConstants.SYB_APPID);
+        params.put("version", "11");
+        params.put("trxamt", String.valueOf(trxamt));
+        params.put("reqsn", reqsn);
+        params.put("oldreqsn", oldreqsn);
+        params.put("oldtrxid", oldtrxid);
+        params.put("randomstr", SybUtil.getValidatecode(8));
+        params.put("signtype", SybConstants.SIGN_TYPE);
+        String appkey = "";
+        if (SybConstants.SIGN_TYPE.equals("RSA"))
+            appkey = SybConstants.SYB_RSACUSPRIKEY;
+        else if (SybConstants.SIGN_TYPE.equals("SM2"))
+            appkey = SybConstants.SYB_SM2PPRIVATEKEY;
+        else
+            appkey = SybConstants.SYB_MD5_APPKEY;
+        params.put("sign", SybUtil.unionSign(params, appkey, SybConstants.SIGN_TYPE));
+        byte[] bys = http.postParams(params, true);
+        String result = new String(bys, "UTF-8");
+        Map<String, String> map = handleResult(result);
+        return map;
+    }
+
+    public Map<String, String> query(String reqsn, String trxid) throws Exception {
+        HttpConnectionUtil http = new HttpConnectionUtil(SybConstants.SYB_APIURL + "/unitorder/query");
+        http.init();
+        TreeMap<String, String> params = new TreeMap<String, String>();
+        if (!SybUtil.isEmpty(SybConstants.SYB_ORGID))
+            params.put("orgid", SybConstants.SYB_ORGID);
+        params.put("cusid", SybConstants.SYB_CUSID);
+        params.put("appid", SybConstants.SYB_APPID);
+        params.put("version", "11");
+        params.put("reqsn", reqsn);
+        params.put("trxid", trxid);
+        params.put("randomstr", SybUtil.getValidatecode(8));
+        params.put("signtype", SybConstants.SIGN_TYPE);
+        String appkey = "";
+        if (SybConstants.SIGN_TYPE.equals("RSA"))
+            appkey = SybConstants.SYB_RSACUSPRIKEY;
+        else if (SybConstants.SIGN_TYPE.equals("SM2"))
+            appkey = SybConstants.SYB_SM2PPRIVATEKEY;
+        else
+            appkey = SybConstants.SYB_MD5_APPKEY;
+        params.put("sign", SybUtil.unionSign(params, appkey, SybConstants.SIGN_TYPE));
+        byte[] bys = http.postParams(params, true);
+        String result = new String(bys, "UTF-8");
+        Map<String, String> map = handleResult(result);
+        return map;
+    }
+
+
+    public static Map<String, String> handleResult(String result) throws Exception {
+        System.out.println("ret:" + result);
+        Map map = SybUtil.json2Obj(result, Map.class);
+        if (map == null) {
+            throw new Exception("返回数据错误");
+        }
+        if ("SUCCESS".equals(map.get("retcode"))) {
+            TreeMap tmap = new TreeMap();
+            tmap.putAll(map);
+            String appkey = "";
+            if (SybConstants.SIGN_TYPE.equals("RSA"))
+                appkey = SybConstants.SYB_RSATLPUBKEY;
+            else if (SybConstants.SIGN_TYPE.equals("SM2"))
+                appkey = SybConstants.SYB_SM2TLPUBKEY;
+            else
+                appkey = SybConstants.SYB_MD5_APPKEY;
+            if (SybUtil.validSign(tmap, appkey, SybConstants.SIGN_TYPE)) {
+                System.out.println("签名成功");
+                return map;
+            } else {
+                throw new Exception("验证签名失败");
+            }
+
+        } else {
+            throw new Exception(map.get("retmsg").toString());
+        }
+    }
+
+
+}

+ 228 - 0
src/main/java/common/utils/tl/SybUtil.java

@@ -0,0 +1,228 @@
+package common.utils.tl;
+
+import java.security.KeyFactory;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.PublicKey;
+import java.security.spec.PKCS8EncodedKeySpec;
+import java.security.spec.X509EncodedKeySpec;
+import java.util.Map;
+import java.util.Random;
+import java.util.TreeMap;
+
+import org.apache.commons.codec.binary.Base64;
+import cn.hutool.json.JSONUtil;
+
+public class SybUtil {
+    /**
+     * js转化为实体
+     *
+     * @param <T>
+     * @param jsonstr
+     * @param cls
+     * @return
+     */
+    public static <T> T json2Obj(String jsonstr, Class<T> cls) {
+        return JSONUtil.toBean(jsonstr, cls);
+    }
+
+    /**
+     * md5
+     *
+     * @param b
+     * @return
+     */
+    public static String md5(byte[] b) {
+        try {
+            MessageDigest md = MessageDigest.getInstance("MD5");
+            md.reset();
+            md.update(b);
+            byte[] hash = md.digest();
+            StringBuffer outStrBuf = new StringBuffer(32);
+            for (int i = 0; i < hash.length; i++) {
+                int v = hash[i] & 0xFF;
+                if (v < 16) {
+                    outStrBuf.append('0');
+                }
+                outStrBuf.append(Integer.toString(v, 16).toLowerCase());
+            }
+            return outStrBuf.toString();
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+            return new String(b);
+        }
+    }
+
+    /**
+     * 判断字符串是否为空
+     *
+     * @param s
+     * @return
+     */
+    public static boolean isEmpty(String s) {
+        if (s == null || "".equals(s.trim()))
+            return true;
+        return false;
+    }
+
+    /**
+     * 生成随机码
+     *
+     * @param n
+     * @return
+     */
+    public static String getValidatecode(int n) {
+        Random random = new Random();
+        String sRand = "";
+        n = n == 0 ? 4 : n;// default 4
+        for (int i = 0; i < n; i++) {
+            String rand = String.valueOf(random.nextInt(10));
+            sRand += rand;
+        }
+        return sRand;
+    }
+
+
+    public static boolean validSign(TreeMap<String, String> param,
+                                    String appkey, String signType) throws Exception {
+        if (param != null && !param.isEmpty()) {
+            if (!param.containsKey("sign"))
+                return false;
+            String sign = param.remove("sign");
+            if ("MD5".equals(signType)) {// 如果是md5则需要把md5的key加入到排序
+                param.put("key", appkey);
+            }
+            StringBuilder sb = new StringBuilder();
+            for (Map.Entry<String, String> entry : param.entrySet()) {
+                if (entry.getValue() != null && entry.getValue().length() > 0) {
+                    sb.append(entry.getKey()).append("=")
+                            .append(entry.getValue()).append("&");
+                }
+            }
+            if (sb.length() > 0) {
+                sb.deleteCharAt(sb.length() - 1);
+            }
+            if ("MD5".equals(signType)) {
+                return sign.toLowerCase().equals(
+                        md5(sb.toString().getBytes("UTF-8")).toLowerCase());
+            } else if ("SM2".equals(signType)) {
+                PublicKey publicKey = SmUtil.pubKeySM2FromBase64Str(appkey);
+                return SmUtil.verifySM3SM2(publicKey, "Allinpay", Base64.decodeBase64(sign), sb.toString().getBytes("UTF-8"));
+            } else {
+                return rsaVerifyPublickey(sb.toString(), sign, appkey, "UTF-8");
+            }
+        }
+        return false;
+    }
+
+    public static boolean rsaVerifyPublickey(String content, String sign,
+                                             String publicKey, String charset) throws Exception {
+        try {
+            PublicKey pubKey = getPublicKeyFromX509("RSA",
+                    Base64.decodeBase64(publicKey.getBytes()));
+            return rsaVerifyPublickey(content, sign, pubKey, charset);
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new Exception("RSAcontent = " + content + ",sign=" + sign
+                    + ",charset = " + charset, e);
+        }
+    }
+
+    public static boolean rsaVerifyPublickey(String content, String sign,
+                                             PublicKey pubKey, String charset) throws Exception {
+        try {
+            java.security.Signature signature = java.security.Signature
+                    .getInstance("SHA1WithRSA");
+
+            signature.initVerify(pubKey);
+
+            if (charset == null || "".equals(charset)) {
+                signature.update(content.getBytes());
+            } else {
+                signature.update(content.getBytes(charset));
+            }
+
+            return signature.verify(Base64.decodeBase64(sign.getBytes()));
+        } catch (Exception e) {
+            throw e;
+        }
+    }
+
+    public static String unionSign(TreeMap<String, String> params, String appkey,
+                                   String signType) throws Exception {
+        // TODO Auto-generated method stub
+
+        params.remove("sign");
+        if ("MD5".equals(signType)) {// 如果是md5则需要把md5的key加入到排序
+            params.put("key", appkey);
+        }
+        StringBuilder sb = new StringBuilder();
+        for (Map.Entry<String, String> entry : params.entrySet()) {
+            if (entry.getValue() != null && entry.getValue().length() > 0) {
+                sb.append(entry.getKey()).append("=").append(entry.getValue())
+                        .append("&");
+            }
+        }
+        if (sb.length() > 0) {
+            sb.deleteCharAt(sb.length() - 1);
+        }
+        String sign = "";
+        if ("MD5".equals(signType)) {
+            System.out.println(sb.toString());
+            sign = md5(sb.toString().getBytes("UTF-8"));// 记得是md5编码的加签
+            params.remove("key");
+        } else if ("SM2".equals(signType)) {
+            System.out.println(sb.toString());
+            PrivateKey privkey = SmUtil.privKeySM2FromBase64Str(appkey);
+            sign = SmUtil.signSM3SM2RetBase64(privkey, params.get("appid"), sb.toString().getBytes("UTF-8"));//签名
+        } else {
+            System.out.println(sb.toString());
+            sign = rsaSign(sb.toString(), appkey, "UTF-8");
+        }
+        return sign;
+    }
+
+    public static String rsaSign(String content, String privateKey,
+                                 String charset) throws Exception {
+        PrivateKey priKey = getPrivateKeyFromPKCS8("RSA",
+                Base64.decodeBase64(privateKey.getBytes()));
+        return rsaSign(content, priKey, charset);
+    }
+
+    public static String rsaSign(String content, byte[] privateKey,
+                                 String charset) throws Exception {
+        PrivateKey priKey = getPrivateKeyFromPKCS8("RSA", privateKey);
+        return rsaSign(content, priKey, charset);
+    }
+
+    public static String rsaSign(String content, PrivateKey priKey,
+                                 String charset) throws Exception {
+        java.security.Signature signature = java.security.Signature
+                .getInstance("SHA1WithRSA");
+        signature.initSign(priKey);
+        if (charset == null || "".equals(charset)) {
+            signature.update(content.getBytes());
+        } else {
+            signature.update(content.getBytes(charset));
+        }
+        byte[] signed = signature.sign();
+
+        return new String(Base64.encodeBase64(signed));
+    }
+
+    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
+                                                    byte[] encodedKey) throws Exception {
+
+        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
+
+        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
+    }
+
+    public static PublicKey getPublicKeyFromX509(String algorithm,
+                                                 byte[] encodedKey) throws Exception {
+        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
+
+        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
+    }
+}