|
@@ -0,0 +1,169 @@
|
|
|
+package com.zhongzheng.modules.sdk.service.impl;
|
|
|
+
|
|
|
+import cn.hutool.core.lang.Validator;
|
|
|
+import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.google.gson.GsonBuilder;
|
|
|
+import com.google.gson.JsonArray;
|
|
|
+import com.google.gson.JsonObject;
|
|
|
+import com.zhongzheng.common.core.redis.RedisCache;
|
|
|
+import com.zhongzheng.common.exception.CustomException;
|
|
|
+import com.zhongzheng.common.utils.bank.DCCryptor;
|
|
|
+import com.zhongzheng.common.utils.bank.DCHelper;
|
|
|
+import com.zhongzheng.modules.sdk.service.IZsBankService;
|
|
|
+import com.zhongzheng.modules.sdk.service.NuonuoService;
|
|
|
+import nuonuo.open.sdk.NNOpenSDK;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.beans.factory.annotation.Value;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.*;
|
|
|
+import java.net.URLEncoder;
|
|
|
+
|
|
|
+@Service
|
|
|
+public class ZsBankServiceImpl implements IZsBankService {
|
|
|
+ private static final Logger LOGGER = LoggerFactory.getLogger(ZsBankServiceImpl.class);
|
|
|
+ @Value("${ZsBank.publickey}")
|
|
|
+ private String publickey;
|
|
|
+ @Value("${ZsBank.privatekey}")
|
|
|
+ private String privatekey;
|
|
|
+
|
|
|
+ private static Base64.Encoder encoder = Base64.getEncoder();
|
|
|
+ private static Base64.Decoder decoder = Base64.getDecoder();
|
|
|
+
|
|
|
+ private static final String ALG_SM = "SM"; // 采用国密算法
|
|
|
+
|
|
|
+ private static String UID = "N002463262"; // 测试的用户编号
|
|
|
+
|
|
|
+ private static String URL = "http://cdctest.cmburl.cn:80/cdcserver/api/v2"; // 银行服务地址(测试)
|
|
|
+ private static String bankpubkey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5Ec7viMyQC5SShRz1jP0IQRLLVGDQ4f1rgZwtxT4ZOgnWxUoAHquj2yIrgFjNpWVnt/1dJGtXWkpp2UN3jMI5ubjVQkL0OFD+8r0IFXYAARsCLAwVLF0LE487KvVRaQC7A7rPlFfBtE/v++KajzMuDauNlIASYobcFKYdZ89vIfE/xMg/44QJqQ2XBkoMnJ7ul0kMdh4YWOQnO0qqvXD2eK3KPaXMRtxieGsVBgsvtETprw98bTl9tPUBUrneyirrccS8/Z6raV6nioyx2RzrMld8YnjlnV2YTJpNAlG+y/wLoKY55Rkjcvg9wSe8qbI/VtYVQfQz8gfeUzFQTKKCwIDAQAB"; // 银行公钥
|
|
|
+
|
|
|
+ private static String privkey = "MIIEowIBAAKCAQEAwN7xTseqQs1pNA/+gTgXRqcxCYfkxDTsckfqf3O2ndsvJS5T\n" +
|
|
|
+ "8Fb0oHTyjy0HjrKLASWWUKfhQGXPHbo1FQd+0TyHxSza55+HtXquUq7QsAITHCu3\n" +
|
|
|
+ "U7aslvC7xe6/2E7nhu1TausF1nSyB1o4xVEjZyjrdQpTID0JvG8BtA5Yem9YDBCM\n" +
|
|
|
+ "ZHBxvarQHVqdBsqo2G3M09qeUDbY3DuBgdiVAw0ApIM8mKGj4jsWmRSnypuxl40B\n" +
|
|
|
+ "jWAr6Xgk44MpSGHndhiFXGvfMRRYEd8Z30w32QlB+Gjk8rQwXnvxG8YCBPYqXVkq\n" +
|
|
|
+ "wld81bHFFz5zHQ0qekPhD8RrFimPn+RaD9VNfwIDAQABAoIBAQCxUUZQw0hJOkgq\n" +
|
|
|
+ "UToO2t6rWjK/LGyp5m4rcuqoWl3eKxDhAgKxx4AHtPz7nM6B5qvdVg0oAfAZIICW\n" +
|
|
|
+ "OAdtWgLBowC/yklHAWfm9O8nnQjHiGDBWX+mOx/ZdWFsy98cow5BAhfbCE/Jpme2\n" +
|
|
|
+ "UsA2yC3gPcKbS+64iOVWlEfgnf/CLte/dE0eAMfsp5wXpwv3ygA4wtyd2X2P+y6s\n" +
|
|
|
+ "+WYBKSvNMS08W4dsxwU9Q3AG3hS0Uab09qIPNS8tEMZ2L1tl0/VvkrAYjayM1CcK\n" +
|
|
|
+ "CrSnwtH6eJVi4WQxL1K3QxyxDKucsOlqSHg++4VMpGZNpvstn3IsY3PyCgfsODvH\n" +
|
|
|
+ "aoygvDBhAoGBAPxxdcI9stK9bIGSms0FqbVXYj8WmAjE/M9B7ECToWRQg65Gf8MY\n" +
|
|
|
+ "PyUSkY2mbDHwf+yPsUb5Oli+a2GW8BwmJWeXEIy0lQxa1TS2b7CN6XJtZVnjEgiZ\n" +
|
|
|
+ "d7bXy/j69r/C4CMlfbrRWnUGftKr/U7ynaGs10/bISeW12E7WdLV5+kDAoGBAMOW\n" +
|
|
|
+ "nEzAFMPFzG9p/GtYpWU5jMNSiakzfm6n9Nwr7dFGnLhVGtO6act1bm/WB26NAgIE\n" +
|
|
|
+ "ArhcitoKrI346nfkoZLXBpzzyJgFx4r31d1RN9Vsrt6AEywlwnLwHk2HXtCwmqre\n" +
|
|
|
+ "hZ4I741S2rHlaT8ifNwLyjW2sbw9QnpC3RL7R3rVAoGAOI/Dbs4cLxO6KB4NCTrn\n" +
|
|
|
+ "l3YI0VHiprRcYKPIp39sfel8V6P8JF5eZ5QNgMt1GotkXkCj298jr5aawLbs/aGe\n" +
|
|
|
+ "Z+N1FdGwQ6BmfPUTeV+SmszgFI/IDp00MYeQcCzq9HRZfAZ+cUlPF0FpURKwIuxB\n" +
|
|
|
+ "XWQ4qe/TMeeeQm7l5VOALrkCgYAljLa5LW9PHpxfD3P8j+pBAsl5flEbgN1XFTu3\n" +
|
|
|
+ "QV/I+8t+wCgEWheRjhwDsI2AteWayXZUOsAVmFMEdrNdDTHP5SRJ4auzM/jZPzd5\n" +
|
|
|
+ "4+vaN6Fi6ifEJAOu2VaX/9M+MYmgIFR6wLBs62k9GhQYoOBjxoetxENfJkuq+UdE\n" +
|
|
|
+ "K6XPeQKBgFvf+SUrg7hFpRRyCq+DehdMQk1TJnEPTNLOalfrA/319KA8LGa0Q+ay\n" +
|
|
|
+ "5c2mDc9F//yAJEAT1WTEqHnvKBQvjofFAGRntoCT8anAnskSytwwpltKqDcpoKx/\n" +
|
|
|
+ "hVK+eVL47wuFroCBLGj0Zm3I7S+saGGmVllEky4jceE7IMTN7i6W";
|
|
|
+ private static String sm4key = "VuAzSWQhsoNqzn0K";//"1234567890123456"; // 用户的对称密钥
|
|
|
+
|
|
|
+ @Autowired
|
|
|
+ private RedisCache redisCache;
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean testSearch() {
|
|
|
+ // 组织发送报文
|
|
|
+ JsonObject obj = new JsonObject();
|
|
|
+ JsonObject req = new JsonObject();
|
|
|
+ JsonObject body = new JsonObject();
|
|
|
+ JsonObject head = new JsonObject();
|
|
|
+ head.addProperty("funcode", "DCTRSINF"); //DCLISMOD
|
|
|
+ head.addProperty("userid", UID);
|
|
|
+ head.addProperty("reqid", DCHelper.getTime() + "0000001");
|
|
|
+ body.addProperty("buscod", "N02030");
|
|
|
+ body.addProperty("TEST", "中文");
|
|
|
+ body.addProperty("TEST2", "!@#$%^&*()\\\\///");
|
|
|
+ body.addProperty("TEST3", 12345);
|
|
|
+ JsonArray array = new JsonArray();
|
|
|
+ JsonObject item = new JsonObject();
|
|
|
+ item.addProperty("arrItem1", "qaz");
|
|
|
+ item.addProperty("arrItem2", 123);
|
|
|
+ item.addProperty("arrItem3", true);
|
|
|
+ item.addProperty("arrItem4", "中文");
|
|
|
+
|
|
|
+ array.add(item);
|
|
|
+ body.add("TEST4", array);
|
|
|
+ req.add("head", head);
|
|
|
+ req.add("body", body);
|
|
|
+ obj.add("request", req);
|
|
|
+
|
|
|
+ // 请求发送接收
|
|
|
+ doProcess(obj);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void doProcess(JsonObject jObject) {
|
|
|
+ try {
|
|
|
+ JsonObject object = new JsonObject();
|
|
|
+ // 签名
|
|
|
+ object.addProperty("sigdat", "__signature_sigdat__");
|
|
|
+ object.addProperty("sigtim", DCHelper.getTime());
|
|
|
+ jObject.add("signature", object);
|
|
|
+ String source = DCHelper.serialJsonOrdered(jObject);
|
|
|
+ System.out.println("签名原文: " + source);
|
|
|
+ byte[] signature1 = DCCryptor.CMBSM2SignWithSM3(getID_IV(), decoder.decode(privkey), source.getBytes(StandardCharsets.UTF_8));
|
|
|
+ String sigdat1 = new String(encoder.encode(signature1));
|
|
|
+ System.out.println("签名结果: " + sigdat1);
|
|
|
+ object.addProperty("sigdat", sigdat1);
|
|
|
+
|
|
|
+ // SM4-CBC加密
|
|
|
+ String plaintxt = jObject.toString();
|
|
|
+ System.out.println("加密前req: " + plaintxt);
|
|
|
+ byte[] enInput = DCCryptor.CMBSM4EncryptWithCBC(sm4key.getBytes(), getID_IV(), plaintxt.getBytes(StandardCharsets.UTF_8));
|
|
|
+
|
|
|
+ String req = new String(encoder.encode(enInput));
|
|
|
+ System.out.println("加密后req: " + req);
|
|
|
+
|
|
|
+ // 发送请求
|
|
|
+ HashMap<String, String> map = new HashMap<>();
|
|
|
+ map.put("UID", UID);
|
|
|
+ map.put("ALG", ALG_SM);
|
|
|
+ map.put("DATA", URLEncoder.encode(req, "utf-8"));
|
|
|
+ map.put("FUNCODE", "DCLISMOD");
|
|
|
+ String res = DCHelper.doPostForm(URL, map);
|
|
|
+ System.out.println("res: " + res);
|
|
|
+ try {
|
|
|
+ decoder.decode(res);
|
|
|
+ } catch (Exception e) {
|
|
|
+ System.err.println("访问返回错误.");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解密请求
|
|
|
+ String resplain = new String(DCCryptor.CMBSM4DecryptWithCBC(sm4key.getBytes(), getID_IV(), decoder.decode(res)), StandardCharsets.UTF_8);
|
|
|
+ System.out.println("res decrypt: " + resplain);
|
|
|
+
|
|
|
+ // 验签
|
|
|
+ JsonObject object2 = new GsonBuilder().create().fromJson(resplain, JsonObject.class);
|
|
|
+ JsonObject object3 = object2.getAsJsonObject("signature");
|
|
|
+ String resSign = object3.get("sigdat").getAsString();
|
|
|
+ object3.addProperty("sigdat", "__signature_sigdat__");
|
|
|
+ object2.add("signature", object3);
|
|
|
+ String resSignSource = DCHelper.serialJsonOrdered(object2);
|
|
|
+ System.out.println("验签原文: " + resSignSource);
|
|
|
+ System.out.println("验签签名值: " + resSign);
|
|
|
+ boolean verify = DCCryptor.CMBSM2VerifyWithSM3(getID_IV(), decoder.decode(bankpubkey), resSignSource.getBytes(StandardCharsets.UTF_8), decoder.decode(resSign));
|
|
|
+ System.out.println("验签结果: " + verify);
|
|
|
+ }catch (Exception e){
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ private static byte[] getID_IV() {
|
|
|
+ String uid = UID; // 请替换为实际的用户UID
|
|
|
+ String userid = uid + "0000000000000000";
|
|
|
+ return userid.substring(0, 16).getBytes();
|
|
|
+ }
|
|
|
+}
|