From e6c5b29a47579759dd033c0c520bcf0f986abb59 Mon Sep 17 00:00:00 2001
From: xiaoyong931011 <15274802129@163.com>
Date: Wed, 19 Apr 2023 11:00:28 +0800
Subject: [PATCH] 拉卡拉收银台
---
src/test/java/cc/mrbird/febs/ProfitTest.java | 13 +
src/api_cert.cer | 22 ++
src/api_private_key.pem | 28 +++
pom.xml | 11 +
src/main/java/cc/mrbird/febs/pay/service/LaKaLaService.java | 9 +
src/main/java/cc/mrbird/febs/pay/service/impl/LaKaLaServiceImpl.java | 327 ++++++++++++++++++++++++++++++++++++++++
src/lkl-apigw-v2.cer | 25 +++
7 files changed, 431 insertions(+), 4 deletions(-)
diff --git a/pom.xml b/pom.xml
index d146f33..4c8219c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -28,6 +28,17 @@
</properties>
<dependencies>
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcprov-jdk15on</artifactId>
+ <version>1.68</version>
+ </dependency>
+
+ <dependency>
+ <groupId>org.bouncycastle</groupId>
+ <artifactId>bcpkix-jdk15on</artifactId>
+ <version>1.68</version>
+ </dependency>
<!-- 图片压缩-->
<dependency>
<groupId>net.coobird</groupId>
diff --git a/src/api_cert.cer b/src/api_cert.cer
new file mode 100644
index 0000000..b2be121
--- /dev/null
+++ b/src/api_cert.cer
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDoDCCAoigAwIBAgIGAYSJQP1BMA0GCSqGSIb3DQEBBQUAMGAxFDASBgNVBAMM
+C0xBS0FMQS1MQU9QMQswCQYDVQQGEwJDTjEXMBUGA1UECgwOTGFrYWxhIENvLixM
+dGQxDzANBgNVBAsMBkxLTC1ZRjERMA8GA1UEBwwIc2hhbmdoYWkwHhcNMjIxMTE4
+MDU0MDQ4WhcNMzIxMTE4MDU0MDQ4WjBgMRQwEgYDVQQDDAtMQUtBTEEtTEFPUDEL
+MAkGA1UEBhMCQ04xFzAVBgNVBAoMDkxha2FsYSBDby4sTHRkMQ8wDQYDVQQLDAZM
+S0wtWUYxETAPBgNVBAcMCHNoYW5naGFpMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAjf7Ff88dObCuKrMSWh1CwoHn6flW+e9/+CG0iS4Yacix45Tc+f0h
+ddoICfFvh/EgbX1RHJWI7H0Vc/7OO2FsNm6b4HO2RUXTiFQ1nBpOKuH4XtaDssM8
+Yl/4fu4grZ8qFtBDQxh/5cEFGRWNL9Do/h4JnvhOKy776LU5Ochj+PLJLHUGjT0E
+LsqgRIAGKw+gt7yAfvbaUlpy+f0RvP08ekToRyBtqBJfOd8hbosJfHf0zUpmtWoD
+Km4xdGeOWBQNAkysnkGU55EMbfvfNi72LFGmvorr1nDCtnHQ9BMDlq1KabHtKG5I
+NFD3IyBcqKlzc5qFCuayMZWJD5imNE6zNwIDAQABo2AwXjAPBgNVHRMECDAGAQH/
+AgEAMB8GA1UdIwQYMBaAFJDzHLFCYeg8o41u6l8vKkHDGKAoMB0GA1UdDgQWBBSQ
+8xyxQmHoPKONbupfLypBwxigKDALBgNVHQ8EBAMCBsAwDQYJKoZIhvcNAQEFBQAD
+ggEBADSWmpY2kKB2qdFZ1TYd/uPn8ejC1uZIIlBRh07yhQVFABhBSlcGaoBN+Vwv
+rMcqkr4AWX7c63W29+axWVLrwSeFC9ViQqolL3I9cA3PDzmyyzS1T8OLdrr+y7W9
+ixMAnc70O0vEa5vhb/PFu+5qnelSwhIFOz+rgs6ty92gzMHISYBxaPfQGxuTDG3H
+xpL3S+ef/+vOpZjFSv+EvdVPdfPWgMIGFLqaqWEHOKLqpRX/3GAxxSJvWzA+le+q
+IJE7mZF5C+WWd2tn1M/+yHw3PDb2q62MCfe+WmHQNxM/b8JtcC/7lvyhIkOlsi2C
+3nqklUEbOiV7QngV5cuIH2nAS7g=
+-----END CERTIFICATE-----
diff --git a/src/api_private_key.pem b/src/api_private_key.pem
new file mode 100644
index 0000000..d0c646d
--- /dev/null
+++ b/src/api_private_key.pem
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCN/sV/zx05sK4q
+sxJaHULCgefp+Vb573/4IbSJLhhpyLHjlNz5/SF12ggJ8W+H8SBtfVEclYjsfRVz
+/s47YWw2bpvgc7ZFRdOIVDWcGk4q4fhe1oOywzxiX/h+7iCtnyoW0ENDGH/lwQUZ
+FY0v0Oj+Hgme+E4rLvvotTk5yGP48sksdQaNPQQuyqBEgAYrD6C3vIB+9tpSWnL5
+/RG8/Tx6ROhHIG2oEl853yFuiwl8d/TNSma1agMqbjF0Z45YFA0CTKyeQZTnkQxt
++982LvYsUaa+iuvWcMK2cdD0EwOWrUppse0obkg0UPcjIFyoqXNzmoUK5rIxlYkP
+mKY0TrM3AgMBAAECggEAPbx9hho4rLKCpxIAcqmyMvtkJ7g+9qAI1YtiARrHhoa5
+wSciBJboC2Nmh1wvj71oyfHoaDMjux6PS0WHyQ2MjQX+Q9JLd0bqt6VVQa+2OLLS
+1/kQfZKhGGx9kEJcduBy3kRiWjO2t9/6JXPXVOjRxFqu+C0hX2koIX9ZiCP2Q3A0
+TdlaHillZkwtVQYi85ywPOOKUbl510lIbn5l4dV+jXXDWXAjxoFvgdxtMguXP78m
+cfBsNMit04i5VzhTkG0shUBfpSsdQO3hMlkqYCEUMuh6zIdSZ2xDIEzoOkw7H93k
+r6FNSWxa1kO//roB6Z4niH5BF+oKGY4bkjg0AyYlQQKBgQDbsWJ4UhTira7Hu98V
+j0vy9V5YqmUGOxpxG6gKZnJSNRBZ8qDPXSFoc/ab7Tol7uiNnTcwApOXXZbfEUtg
+y1U6W4ahw5VriZfiV321gkZDP/LazVTvYOTbUrl2YKNnIqRZ6iMehF6shnEPmLZI
+C3MluxCR0t44F8sv2OcNZ+ygEQKBgQCldjTAFKLhBHa3g7Eqc7KJt8SskltZ7sra
+m+BfXVck0l1R1i7kXWb22e0O3x+baiPpoXe6r48wDWXOQ4rEqOVNpLL8zolsn57o
+EZ670ARU8nk7MgFB9JRFuFo2COSqFzMSMaCyHjcjDL56+DP9L7E8LXaML1N6aOw1
+mMTW2Z/mxwKBgQDaMqTtggCyXvR/9i2MmUVCqsco4xvxg1Qw0NomcjfLRF7YJ23m
+ZsYem0Zs+cHOGSoqNOKyMWzrYo3NQb0PBwTAMFVYZwwJwZ/zsxfs5dXpRyNqg5N/
+KUpENzZyx2qjrbl0gGKfFbN+QQ0cA33PsmeMKu47FyeUqLUq8ZASNYzEMQKBgQCk
+4Y0hV68TohoXN3Elh5ODbw/alCHaFX4pqClHfsEnHUYHFfM2d+jx1ipHpopdmcBd
+wRyJeQar8L3hdCblYBTYcWY3TC1fhBSa12whZeHbMKEkHuln6yyR6Wpj7CrJYELx
+P2kN9dQl5j4uVgWgqJTqDbfTbBm4orO3mRuVqdmQ4wKBgHJ0/ba40kzvQCGSv+Nh
+wlDKF23JbD+Wu1yFetylv6n3a9Py1TlxFZ1nPcm10ObFAAKKZEKmBeLrDTgBQP3T
+Zv5R71lRTLIGeT6x5W/CBms/MTbgVWoUw7crq9KE0nEqPvKr/uswAJI05yDN4cEU
+W8/IpLOZtPBO9X73f/kLE8WJ
+-----END PRIVATE KEY-----
diff --git a/src/lkl-apigw-v2.cer b/src/lkl-apigw-v2.cer
new file mode 100644
index 0000000..12723eb
--- /dev/null
+++ b/src/lkl-apigw-v2.cer
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIEMTCCAxmgAwIBAgIGAXRTgcMnMA0GCSqGSIb3DQEBCwUAMHYxCzAJBgNVBAYT
+AkNOMRAwDgYDVQQIDAdCZWlKaW5nMRAwDgYDVQQHDAdCZWlKaW5nMRcwFQYDVQQK
+DA5MYWthbGEgQ28uLEx0ZDEqMCgGA1UEAwwhTGFrYWxhIE9yZ2FuaXphdGlvbiBW
+YWxpZGF0aW9uIENBMB4XDTIwMTAxMDA1MjQxNFoXDTMwMTAwODA1MjQxNFowZTEL
+MAkGA1UEBhMCQ04xEDAOBgNVBAgMB0JlaUppbmcxEDAOBgNVBAcMB0JlaUppbmcx
+FzAVBgNVBAoMDkxha2FsYSBDby4sTHRkMRkwFwYDVQQDDBBBUElHVy5MQUtBTEEu
+Q09NMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt1zHL54HiI8d2sLJ
+lwoQji3/ln0nsvfZ/XVpOjuB+1YR6/0LdxEDMC/hxI6iH2Rm5MjwWz3dmN/6BZeI
+gwGeTOWJUZFARo8UduKrlhC6gWMRpAiiGC8wA8stikc5gYB+UeFVZi/aJ0WN0cpP
+JYCvPBhxhMvhVDnd4hNohnR1L7k0ypuWg0YwGjC25FaNAEFBYP9EYUyCJjE//9Z7
+sMzHR9SJYCqqo6r9bOH9G6sWKuEp+osuAh+kJIxJMHfipw7w3tEcWG0hce9u/el4
+cYJtg8/PPMVoccKmeCzMvarr7jdKP4lenJbtwlgyfs+JgNu60KMUJH8RS72wC9NY
+uFz09wIDAQABo4HVMIHSMIGSBgNVHSMEgYowgYeAFCnH4DkZPR6CZxRn/kIqVsMo
+dJHpoWekZTBjMQswCQYDVQQGEwJDTjEQMA4GA1UECAwHQmVpSmluZzEQMA4GA1UE
+BwwHQmVpSmluZzEXMBUGA1UECgwOTGFrYWxhIENvLixMdGQxFzAVBgNVBAMMDkxh
+a2FsYSBSb290IENBggYBaiUALIowHQYDVR0OBBYEFJ2Kx9YZfmWpkKFnC33C0r5D
+K3rFMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUA
+A4IBAQBZoeU0XyH9O0LGF9R+JyGwfU/O5amoB97VeM+5n9v2z8OCiIJ8eXVGKN9L
+tl9QkpTEanYwK30KkpHcJP1xfVkhPi/cCMgfTWQ5eKYC7Zm16zk7n4CP6IIgZIqm
+TVGsIGKk8RzWseyWPB3lfqMDR52V1tdA1S8lJ7a2Xnpt5M2jkDXoArl3SVSwCb4D
+AmThYhak48M++fUJNYII9JBGRdRGbfJ2GSFdPXgesUL2CwlReQwbW4GZkYGOg9LK
+CNPK6XShlNdvgPv0CCR08KCYRwC3HZ0y1F0NjaKzYdGNPrvOq9lA495ONZCvzYDo
+gmsu/kd6eqxTs/JwdaIYr4sCMg8Z
+-----END CERTIFICATE-----
diff --git a/src/main/java/cc/mrbird/febs/pay/service/LaKaLaService.java b/src/main/java/cc/mrbird/febs/pay/service/LaKaLaService.java
new file mode 100644
index 0000000..451ffde
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/service/LaKaLaService.java
@@ -0,0 +1,9 @@
+package cc.mrbird.febs.pay.service;
+
+public interface LaKaLaService {
+
+ /**
+ * 验证签名
+ */
+ boolean verifyCreateOrder();
+}
diff --git a/src/main/java/cc/mrbird/febs/pay/service/impl/LaKaLaServiceImpl.java b/src/main/java/cc/mrbird/febs/pay/service/impl/LaKaLaServiceImpl.java
new file mode 100644
index 0000000..404782c
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/pay/service/impl/LaKaLaServiceImpl.java
@@ -0,0 +1,327 @@
+package cc.mrbird.febs.pay.service.impl;
+
+import cc.mrbird.febs.pay.service.LaKaLaService;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.io.IOUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.springframework.stereotype.Service;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+import java.io.*;
+import java.security.*;
+import java.security.cert.*;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.PKCS8EncodedKeySpec;
+
+@Slf4j
+@Service
+public class LaKaLaServiceImpl implements LaKaLaService {
+
+
+
+ /**
+ * 字符集固定 utf-8
+ */
+ public static final String ENCODING = "utf-8";
+
+ /**
+ * API schema ,固定 LKLAPI-SHA256withRSA
+ */
+ public final static String SCHEMA = "LKLAPI-SHA256withRSA";
+
+ /**
+ * 接入 appid
+ */
+ public static final String appid = "OP00000418";
+// public static final String appid = "800000010334001";
+
+ /**
+ * 商户证书序列号,和商户私钥对应
+ */
+// public static final String mchSerialNo = "017d6ae9ad6e";
+ public static final String mchSerialNo = "01848940fd41";
+
+ /**
+ * 商户证书私钥,用于请求签名
+ */
+ public static final String merchantPrivateKeyPath = "./src/api_private_key.pem";
+
+ /**
+ * 拉卡拉公钥证书,用于response签名验证,务必区分测试环境和生产环境证书
+ */
+ public static final String lklCertificatePath = "./src/lkl-apigw-v2.cer";
+
+ /**
+ * api请求地址
+ */
+ public final static String apiUrl = "https://test.wsmsd.cn/sit";
+
+ private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
+
+ private static final SecureRandom RANDOM = new SecureRandom();
+
+
+ @Override
+ public boolean verifyCreateOrder() {
+ try {
+ String apiPath = "/api/v3/labs/trans/micropay";
+ String body = "{\n" +
+ " \"req_time\": \"20210907150256\",\n" +
+ " \"version\": \"3.0\",\n" +
+ " \"out_org_code\": \"OP00000003\",\n" +
+ " \"req_data\": {\n" +
+ " \"merchant_no\": \"8222900701107M5\",\n" +
+ " \"term_no\": \"A1062976\",\n" +
+ " \"out_trade_no\": \"FD660E1FAA3A4470933CDEDAE1EC1D8E\",\n" +
+ " \"auth_code\": \"135178236713755038\",\n" +
+ " \"total_amount\": \"23\",\n" +
+ " \"location_info\": {\n" +
+ " \"request_ip\": \"10.176.1.192\",\n" +
+ " \"location\": \"+37.123456789,-121.123456789\"\n" +
+ " },\n" +
+ " \"out_order_no\": \"08F4542EEC6A4497BC419161747A92FA1\"\n" +
+ " }\n" +
+ "}";
+
+
+ String authorization = getAuthorization(body);
+ HttpResponse response = post(apiUrl + apiPath, body, authorization);
+ if (response.getStatusLine().getStatusCode() != 200) {
+ System.out.println("请求失败,statusCode " + response.getStatusLine()
+ + IOUtils.toString(response.getEntity().getContent(), ENCODING));
+ return false;
+ }
+
+ String appid = getHeadValue(response, "Lklapi-Appid");
+ String lklapiSerial = getHeadValue(response, "Lklapi-Serial");
+ String timestamp = getHeadValue(response, "Lklapi-Timestamp");
+ String nonce = getHeadValue(response, "Lklapi-Nonce");
+ String signature = getHeadValue(response, "Lklapi-Signature");
+ String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING);
+
+ System.out.println("responseStr " + responseStr);
+
+ String source = appid + "\n" + lklapiSerial + "\n" + timestamp + "\n" + nonce + "\n" + responseStr + "\n";
+
+ System.out.println("source " + source);
+
+ X509Certificate lklCertificate = loadCertificate(new FileInputStream(new File(lklCertificatePath)));
+
+ boolean verify = verify(lklCertificate, source.getBytes(ENCODING), signature);
+
+ if (verify) {
+ System.out.println("验签成功");
+ return true;
+ } else {
+ System.err.println("验签失败");
+ return false;
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return false;
+ }
+
+// public static void main(String[] args) {
+// try {
+// String apiPath = "/api/v3/labs/trans/micropay";
+//
+// String body = "{\n" +
+// " \"req_time\": \"20210907150256\",\n" +
+// " \"version\": \"3.0\",\n" +
+// " \"out_org_code\": \"OP00000003\",\n" +
+// " \"req_data\": {\n" +
+// " \"merchant_no\": \"822290070111135\",\n" +
+// " \"term_no\": \"29034705\",\n" +
+// " \"out_trade_no\": \"FD660E1FAA3A4470933CDEDAE1EC1D8E\",\n" +
+// " \"auth_code\": \"135178236713755038\",\n" +
+// " \"total_amount\": \"123\",\n" +
+// " \"location_info\": {\n" +
+// " \"request_ip\": \"10.176.1.192\",\n" +
+// " \"location\": \"+37.123456789,-121.123456789\"\n" +
+// " },\n" +
+// " \"out_order_no\": \"08F4542EEC6A4497BC419161747A92FA\"\n" +
+// " }\n" +
+// "}";
+//
+//
+// String authorization = getAuthorization(body);
+// HttpResponse response = post(apiUrl + apiPath, body, authorization);
+// if (response.getStatusLine().getStatusCode() != 200) {
+// System.out.println("请求失败,statusCode " + response.getStatusLine()
+// + IOUtils.toString(response.getEntity().getContent(), ENCODING));
+// return;
+// }
+//
+// String appid = getHeadValue(response, "Lklapi-Appid");
+// String lklapiSerial = getHeadValue(response, "Lklapi-Serial");
+// String timestamp = getHeadValue(response, "Lklapi-Timestamp");
+// String nonce = getHeadValue(response, "Lklapi-Nonce");
+// String signature = getHeadValue(response, "Lklapi-Signature");
+// String responseStr = IOUtils.toString(response.getEntity().getContent(), ENCODING);
+//
+// System.out.println("responseStr " + responseStr);
+//
+// String source = appid + "\n" + lklapiSerial + "\n" + timestamp + "\n" + nonce + "\n" + responseStr + "\n";
+//
+// System.out.println("source " + source);
+//
+// X509Certificate lklCertificate = loadCertificate(new FileInputStream(new File(lklCertificatePath)));
+//
+// boolean verify = verify(lklCertificate, source.getBytes(ENCODING), signature);
+//
+// if (verify) {
+// System.out.println("验签成功");
+//
+// // TODO: 业务处理
+//
+// } else {
+// System.err.println("验签失败");
+// }
+//
+// } catch (Exception e) {
+// e.printStackTrace();
+// }
+//
+// }
+
+ public HttpResponse post(String url, String message, String authorization) throws Exception {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ X509TrustManager tm = new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(X509Certificate[] xcs, String str) {}
+ public void checkServerTrusted(X509Certificate[] xcs, String str) {}
+ };
+ HttpClient http = new DefaultHttpClient();
+ ClientConnectionManager ccm = http.getConnectionManager();
+ ctx.init(null, new TrustManager[] { tm }, null);
+ SSLSocketFactory ssf = new SSLSocketFactory(ctx);
+ ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ SchemeRegistry registry = ccm.getSchemeRegistry();
+ registry.register(new Scheme("https", ssf,443));
+ HttpPost post = new HttpPost(url);
+ StringEntity myEntity = new StringEntity(message, ENCODING);
+ post.setEntity(myEntity);
+ post.setHeader("Authorization", SCHEMA + " " + authorization);
+ post.setHeader("Accept", "application/json");
+ post.setHeader("Content-Type", "application/json");
+ return http.execute(post);
+ }
+
+ protected long generateTimestamp() {
+ return System.currentTimeMillis() / 1000;
+ }
+
+ protected String generateNonceStr() {
+ char[] nonceChars = new char[32];
+ for (int index = 0; index < nonceChars.length; ++index) {
+ nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length()));
+ }
+ return new String(nonceChars);
+ }
+
+ public final String getAuthorization(String body) throws IOException {
+ String nonceStr = generateNonceStr();
+ long timestamp = generateTimestamp();
+
+ String message = appid + "\n" + mchSerialNo + "\n" + timestamp + "\n" + nonceStr + "\n" + body + "\n";
+
+ System.out.println("getToken message : " + message);
+
+ PrivateKey merchantPrivateKey = loadPrivateKey(new FileInputStream(new File(merchantPrivateKeyPath)));
+
+ String signature = this.sign(message.getBytes(ENCODING), merchantPrivateKey);
+
+ String authorization = "appid=\"" + appid + "\"," + "serial_no=\"" + mchSerialNo + "\"," + "timestamp=\""
+ + timestamp + "\"," + "nonce_str=\"" + nonceStr + "\"," + "signature=\"" + signature + "\"";
+ System.out.println("authorization message :" + authorization);
+
+ return authorization;
+ }
+
+ public String sign(byte[] message, PrivateKey privateKey) {
+ try {
+ Signature sign = Signature.getInstance("SHA256withRSA");
+ sign.initSign(privateKey);
+ sign.update(message);
+ return new String(Base64.encodeBase64(sign.sign()));
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
+ } catch (SignatureException e) {
+ throw new RuntimeException("签名计算失败", e);
+ } catch (InvalidKeyException e) {
+ throw new RuntimeException("无效的私钥", e);
+ }
+ }
+
+ private static String getHeadValue(HttpResponse response, String key) {
+ return (response.containsHeader(key)) ? response.getFirstHeader(key).getValue() : "";
+ }
+
+ private static boolean verify(X509Certificate certificate, byte[] message, String signature) {
+ try {
+ Signature sign = Signature.getInstance("SHA256withRSA");
+ sign.initVerify(certificate);
+ sign.update(message);
+ byte[] signatureB = Base64.decodeBase64(signature);
+ return sign.verify(signatureB);
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("当前Java环境不支持SHA256withRSA", e);
+ } catch (SignatureException e) {
+ throw new RuntimeException("签名验证过程发生了错误", e);
+ } catch (InvalidKeyException e) {
+ throw new RuntimeException("无效的证书", e);
+ }
+ }
+
+ public static PrivateKey loadPrivateKey(InputStream inputStream) {
+ try {
+ ByteArrayOutputStream array = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int length;
+ while ((length = inputStream.read(buffer)) != -1) {
+ array.write(buffer, 0, length);
+ }
+
+ String privateKey = array.toString("utf-8").replace("-----BEGIN PRIVATE KEY-----", "")
+ .replace("-----END PRIVATE KEY-----", "").replaceAll("\\s+", "");
+ KeyFactory kf = KeyFactory.getInstance("RSA");
+ return kf.generatePrivate(new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey)));
+ } catch (NoSuchAlgorithmException e) {
+ throw new RuntimeException("当前Java环境不支持RSA", e);
+ } catch (InvalidKeySpecException e) {
+ throw new RuntimeException("无效的密钥格式");
+ } catch (IOException e) {
+ throw new RuntimeException("无效的密钥");
+ }
+ }
+
+ public static X509Certificate loadCertificate(InputStream inputStream) {
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X509");
+ X509Certificate cert = (X509Certificate) cf.generateCertificate(inputStream);
+
+ cert.checkValidity();
+ return cert;
+ } catch (CertificateExpiredException e) {
+ throw new RuntimeException("证书已过期", e);
+ } catch (CertificateNotYetValidException e) {
+ throw new RuntimeException("证书尚未生效", e);
+ } catch (CertificateException e) {
+ throw new RuntimeException("无效的证书", e);
+ }
+ }
+}
diff --git a/src/test/java/cc/mrbird/febs/ProfitTest.java b/src/test/java/cc/mrbird/febs/ProfitTest.java
index 93679b5..91f2979 100644
--- a/src/test/java/cc/mrbird/febs/ProfitTest.java
+++ b/src/test/java/cc/mrbird/febs/ProfitTest.java
@@ -13,6 +13,7 @@
import cc.mrbird.febs.mall.service.IMallAchieveService;
import cc.mrbird.febs.mall.service.IMemberProfitService;
import cc.mrbird.febs.pay.model.*;
+import cc.mrbird.febs.pay.service.LaKaLaService;
import cc.mrbird.febs.pay.service.UnipayService;
import cc.mrbird.febs.rabbit.consumer.AgentConsumer;
import cc.mrbird.febs.rabbit.producter.AgentProducer;
@@ -80,10 +81,14 @@
////
//// System.out.println(mallMemberStarIds);
// }
-// @Test
-// public void agentProfit() {
-//// iApiMallOrderInfoService.changeWallet(665L);
-// }
+
+
+ @Autowired
+ private LaKaLaService laKaLaService;
+ @Test
+ public void agentProfit() {
+ laKaLaService.verifyCreateOrder();
+ }
//
//
//// @Test
--
Gitblit v1.9.1