ソースを参照

国通星驿付数据接收入库

lichunlei 6 ヶ月 前
コミット
10f22bdc5d

+ 53 - 0
AppStart/Helper/PublicImportDataService.cs

@@ -139,6 +139,20 @@ namespace MySystem
                                             InsertData(key, content, jobInfo, BrandId);
                                         }
                                     }
+                                    else if (BrandId == 38)
+                                    {
+                                        content = dataList[1];
+                                        if(key.Contains("merchantinfo"))
+                                        {
+                                            JsonData jsonContent = JsonMapper.ToObject(content);
+                                            string sign = jsonContent["sign"].ToString();
+                                            sign = XyfSM2Decrypt(sign);
+                                            string reqdata = jsonContent["reqdatajson"]["reqdata"].ToString();
+                                            string reqdatajson = XyfSM4Decrypt(reqdata, sign);
+                                            content = content.Replace("\"" + reqdata + "\"", reqdatajson);
+                                        }
+                                        InsertData(key, content, jobInfo, BrandId);
+                                    }
                                     else
                                     {
                                         content = dataList[1];
@@ -377,6 +391,28 @@ namespace MySystem
                 {
                     val = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                 }
+                else if (sName.Contains(",") && sName.Contains("|"))
+                {
+                    string[] dlist = sName.Split('|');
+                    foreach(string subd in dlist)
+                    {
+                        string[] flist = subd.Split(',');
+                        if (flist.Length == 2)
+                        {
+                            if (data.Contains("\"" + flist[1] + "\"") && jsonObj[flist[0]].ToJson().Contains("\"" + flist[1] + "\""))
+                            {
+                                val += jsonObj[flist[0]][flist[1]].ToString();
+                            }
+                        }
+                        else if (flist.Length == 3)
+                        {
+                            if (data.Contains("\"" + flist[2] + "\"") && jsonObj[flist[0]].ToJson().Contains("\"" + flist[1] + "\"") && jsonObj[flist[0]][flist[1]].ToJson().Contains("\"" + flist[2] + "\""))
+                            {
+                                val += jsonObj[flist[0]][flist[1]][flist[2]].ToString();
+                            }
+                        }
+                    }
+                }
                 else if (sName.Contains(","))
                 {
                     string[] flist = sName.Split(',');
@@ -1234,6 +1270,23 @@ namespace MySystem
         
         #endregion
 
+        #region 星驿付
+        
+        string XyfPubKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEH1CVYrJ/Y1xHFEavPgPRArGTZ2V9FTqT06R87OpwJblOF/qmsM2QL+62eT+jvETpBAjXzPp2e1SJlhKSWsHalQ=="; //解密推送消息
+        string XyfPriKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg0naAlZl+yns+V6hdbNdZm77iz8/aeI+41ynp/gK0GyigCgYIKoEcz1UBgi2hRANCAAQfUJVisn9jXEcURq8+A9ECsZNnZX0VOpPTpHzs6nAluU4X+qawzZAv7rZ5P6O8ROkECNfM+nZ7VImWEpJawdqV";
+
+        public string XyfSM2Decrypt(string data)
+        {
+            return SMUtil.Sm2Decrypt(data, XyfPriKey);
+        }
+
+        public string XyfSM4Decrypt(string data, string key)
+        {
+            return SMUtil.Sm4Decrypt(key, data);
+        }
+        
+        #endregion
+
 
 
     }

+ 287 - 0
AppStart/Helper/SMUtil.cs

@@ -0,0 +1,287 @@
+using System;
+using System.Text;
+using System.Security.Cryptography;
+using Newtonsoft.Json.Linq;
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Crypto.Engines;
+using Org.BouncyCastle.Crypto.Macs;
+using Org.BouncyCastle.Crypto.Parameters;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Prng;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Crypto.Paddings;
+using Org.BouncyCastle.Crypto.Modes;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Asn1.Sec;
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Asn1.X509;
+using Org.BouncyCastle.Asn1.Pkcs;
+using Org.BouncyCastle.Pkcs;
+using Org.BouncyCastle.Utilities.Encoders;
+
+namespace MySystem
+{
+    public class SMUtil
+    {
+        private const string KEY_ALGORITHM = "AES";
+        public const string SM4_ECB_PKCS5PADDING = "SM4/ECB/PKCS5Padding";
+        public const string ALGORITHM_NAME = "SM4";
+
+        static SMUtil()
+        {
+            // 在 .NET 中不需要像 Java 那样显式注册提供者,BouncyCastle 通过 NuGet 引用即可使用
+        }
+
+        // 生成一个对称秘钥(返回字符串,行为与 Java 版保持一致:base64 后取前 16 个字符)
+        public static string GetSymmetrickey()
+        {
+            try
+            {
+                byte[] keyBytes = new byte[32]; // 256 bits
+                using (var rng = new RNGCryptoServiceProvider())
+                {
+                    rng.GetBytes(keyBytes);
+                }
+                string key = Convert.ToBase64String(keyBytes);
+                if (key.Length >= 16)
+                    key = key.Substring(0, 16);
+                return key;
+            }
+            catch
+            {
+                return string.Empty;
+            }
+        }
+
+        // 生成 SM2 公私钥对,返回 { publicKeyBase64, privateKeyBase64 }
+        public static string[] GenerateSmKey()
+        {
+            try
+            {
+                X9ECParameters ecP = ECNamedCurveTable.GetByName("sm2p256v1");
+                ECDomainParameters domainParams = new ECDomainParameters(ecP.Curve, ecP.G, ecP.N, ecP.H);
+
+                var gen = new ECKeyPairGenerator();
+                var secureRandom = new SecureRandom();
+                var keyGenParam = new ECKeyGenerationParameters(domainParams, secureRandom);
+                gen.Init(keyGenParam);
+                AsymmetricCipherKeyPair pair = gen.GenerateKeyPair();
+
+                // 构造 X.509 SubjectPublicKeyInfo(使用公钥点),以及 PKCS#8 PrivateKeyInfo
+                var pubParam = pair.Public as ECPublicKeyParameters;
+                var privInfo = PrivateKeyInfoFactory.CreatePrivateKeyInfo(pair.Private);
+                // AlgorithmIdentifier: id-ecPublicKey + named curve OID
+                var curveOid = ECNamedCurveTable.GetOid("sm2p256v1");
+                var algId = new Org.BouncyCastle.Asn1.X509.AlgorithmIdentifier(X9ObjectIdentifiers.IdECPublicKey, curveOid);
+                var spki = new SubjectPublicKeyInfo(algId, pubParam.Q.GetEncoded(false));
+                byte[] pubBytes = spki.ToAsn1Object().GetEncoded();
+                byte[] privBytes = privInfo.ToAsn1Object().GetEncoded();
+
+                return new string[] { Convert.ToBase64String(pubBytes), Convert.ToBase64String(privBytes) };
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+        }
+
+        // 从 base64 字符串恢复公钥参数(AsymmetricKeyParameter)
+        public static AsymmetricKeyParameter CreatePublicKey(string publicKeyBase64)
+        {
+            try
+            {
+                byte[] data = Convert.FromBase64String(publicKeyBase64);
+                return PublicKeyFactory.CreateKey(data);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+        }
+
+        // 从 base64 字符串恢复私钥参数
+        public static AsymmetricKeyParameter CreatePrivateKey(string privateKeyBase64)
+        {
+            try
+            {
+                byte[] data = Convert.FromBase64String(privateKeyBase64);
+                return PrivateKeyFactory.CreateKey(data);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+        }
+
+        // SM2 加密(对称秘钥字符串使用 SM2 公钥加密,返回 base64)
+        public static string Sm2Encrypt(string symmetrickey, string pubKeyBase64)
+        {
+            try
+            {
+                var pubParam = CreatePublicKey(pubKeyBase64) as ECPublicKeyParameters;
+                if (pubParam == null) return null;
+                var engine = new SM2Engine();
+                engine.Init(true, new ParametersWithRandom(pubParam, new SecureRandom()));
+                byte[] inBytes = Encoding.UTF8.GetBytes(symmetrickey);
+                byte[] outBytes = engine.ProcessBlock(inBytes, 0, inBytes.Length);
+                return Convert.ToBase64String(outBytes);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+        }
+
+        // SM2 解密(传入 base64 密文和私钥 base64)
+        public static string Sm2Decrypt(string cipherBase64, string priKeyBase64)
+        {
+            try
+            {
+                var priParam = CreatePrivateKey(priKeyBase64) as ECPrivateKeyParameters;
+                if (priParam == null) return null;
+                var engine = new SM2Engine();
+                engine.Init(false, priParam);
+                byte[] inBytes = Convert.FromBase64String(cipherBase64);
+                byte[] outBytes = engine.ProcessBlock(inBytes, 0, inBytes.Length);
+                return Encoding.UTF8.GetString(outBytes);
+            }
+            catch (Exception)
+            {
+                return null;
+            }
+        }
+
+        // SM3 摘要
+        public static byte[] Sm3(byte[] srcData)
+        {
+            var digest = new SM3Digest();
+            digest.BlockUpdate(srcData, 0, srcData.Length);
+            byte[] result = new byte[digest.GetDigestSize()];
+            digest.DoFinal(result, 0);
+            return result;
+        }
+
+        public static string Sm3Hex(string srcData)
+        {
+            byte[] hash = Sm3(Encoding.UTF8.GetBytes(srcData));
+            return Hex.ToHexString(hash);
+        }
+
+        // HMAC-SM3
+        public static byte[] HmacSm3(byte[] key, byte[] srcData)
+        {
+            var mac = new HMac(new SM3Digest());
+            mac.Init(new KeyParameter(key));
+            mac.BlockUpdate(srcData, 0, srcData.Length);
+            byte[] result = new byte[mac.GetMacSize()];
+            mac.DoFinal(result, 0);
+            return result;
+        }
+
+        public static string HmacSm3Hex(string key, string srcData)
+        {
+            byte[] hash = HmacSm3(Encoding.UTF8.GetBytes(key), Encoding.UTF8.GetBytes(srcData));
+            return Hex.ToHexString(hash);
+        }
+
+        // 另一种调用 MessageDigest 的 SM3 实现(使用 BouncyCastle 的 Digest 就足够了)
+        public static byte[] Sm3Bc(byte[] srcData)
+        {
+            return Sm3(srcData);
+        }
+
+        public static string Sm3BcHex(string srcData)
+        {
+            return Sm3Hex(srcData);
+        }
+
+        // SM4 加解密(使用 BouncyCastle 的块加密器和填充)
+        public static string Sm4Encrypt(string symmetrickey, string data)
+        {
+            string algorithmName = SM4_ECB_PKCS5PADDING;
+            byte[] key = Encoding.UTF8.GetBytes(symmetrickey);
+            byte[] iv = Encoding.UTF8.GetBytes(symmetrickey);
+            byte[] cipher = Sm4Core(algorithmName, true, key, iv, Encoding.UTF8.GetBytes(data));
+            return Convert.ToBase64String(cipher);
+        }
+
+        public static string Sm4Decrypt(string symmetrickey, string data)
+        {
+            string algorithmName = SM4_ECB_PKCS5PADDING;
+            byte[] key = Encoding.UTF8.GetBytes(symmetrickey);
+            byte[] iv = Encoding.UTF8.GetBytes(symmetrickey);
+            byte[] plain = Sm4Core(algorithmName, false, key, iv, Convert.FromBase64String(data));
+            return Encoding.UTF8.GetString(plain);
+        }
+
+        private static byte[] Sm4Core(string algorithmName, bool forEncrypt, byte[] key, byte[] iv, byte[] input)
+        {
+            try
+            {
+                // 将 Java 的 "SM4/ECB/PKCS5Padding" 换为 BouncyCastle 可识别的形式
+                string bcName = algorithmName.Replace("PKCS5Padding", "PKCS7Padding");
+                var cipher = CipherUtilities.GetCipher(bcName);
+                ICipherParameters parameters = null;
+                if (algorithmName.Contains("/ECB/"))
+                {
+                    parameters = new KeyParameter(key);
+                }
+                else
+                {
+                    parameters = new ParametersWithIV(new KeyParameter(key), iv);
+                }
+                cipher.Init(forEncrypt, parameters);
+                byte[] outBytes = cipher.DoFinal(input);
+                return outBytes;
+            }
+            catch (Exception ex)
+            {
+                throw new Exception("SM4 operation failed", ex);
+            }
+        }
+
+        // 将 JObject 的 key 转为小写(null 或空值替换为 "")
+        public static JObject DealJSONObj(JObject jsonObj)
+        {
+            var result = new JObject();
+            foreach (var prop in jsonObj.Properties())
+            {
+                JToken val = prop.Value;
+                if (!HasValue(val))
+                    val = "";
+                result[prop.Name.ToLower()] = val;
+            }
+            return result;
+        }
+
+        public static JArray DealJSONArray(JArray jsonArray)
+        {
+            var arr = new JArray();
+            foreach (var item in jsonArray)
+            {
+                if (item is JObject jo)
+                {
+                    arr.Add(DealJSONObj(jo));
+                }
+                else
+                {
+                    arr.Add(item);
+                }
+            }
+            return arr;
+        }
+
+        private static bool HasValue(JToken token)
+        {
+            if (token == null) return false;
+            if (token.Type == JTokenType.Null) return false;
+            if (token.Type == JTokenType.String)
+            {
+                var s = token.ToString();
+                return !string.IsNullOrWhiteSpace(s);
+            }
+            return true;
+        }
+    }
+}

+ 18 - 0
Areas/Api/Controllers/v1/KqController.cs

@@ -470,10 +470,18 @@ namespace MySystem.Areas.Api.Controllers
             {
                 LogHelper.Instance.WriteLog(DateTime.Now.ToString() + content, "WIFI" + KindName + "推送消息");
             }
+            else if (BrandId == 30)
+            {
+                LogHelper.Instance.WriteLog(DateTime.Now.ToString() + content, "拉卡拉" + KindName + "推送消息");
+            }
             else if (BrandId == 34)
             {
                 LogHelper.Instance.WriteLog(DateTime.Now.ToString() + content, "联动掌中宝" + KindName + "推送消息");
             }
+            else if (BrandId == 38)
+            {
+                LogHelper.Instance.WriteLog(DateTime.Now.ToString() + content, "国通星驿付" + KindName + "推送消息");
+            }
             else
             {
                 LogHelper.Instance.WriteLog(DateTime.Now.ToString() + content, "金控" + KindName + "推送消息");
@@ -523,6 +531,16 @@ namespace MySystem.Areas.Api.Controllers
                 obj.Add("code", "200");
                 obj.Add("msg", "success");
             }
+            else if (BrandId == 38)
+            {
+                //{"timestamp":1658460916,"totcount":0,"errormsg":"推送成功","data":null,"errorcode":"00000","datajson":null}
+                obj.Add("timestamp", function.getTimeStamp());
+                obj.Add("totcount", 0);
+                obj.Add("errormsg", "推送成功");
+                obj.Add("data", null);
+                obj.Add("errorcode", "00000");
+                obj.Add("datajson", null);
+            }
             else
             {
                 obj = PublicImportDataService.Instance.CallBack();

+ 7 - 7
Startup.cs

@@ -221,14 +221,14 @@ namespace MySystem
             });
 
             // 必须执行
-            GetSpTimer.Instance.Start(); //定时从redis抓取第三方接收数据
-            SpNoticeHelper.Instance.Start();
-            LogHelper.Instance.Start();
-            CheckWifiData.Instance.Start(); //解析wifi设备通知数据
-            SourceDataToDb.Instance.Start(); //补原始数据
+            // GetSpTimer.Instance.Start(); //定时从redis抓取第三方接收数据
+            // SpNoticeHelper.Instance.Start();
+            // LogHelper.Instance.Start();
+            // CheckWifiData.Instance.Start(); //解析wifi设备通知数据
+            // SourceDataToDb.Instance.Start(); //补原始数据
             
-            RabbitMQClient2.Instance.Conn("SpDataQueue");
-            RabbitMQClient2.Instance.Conn("MainDataQueue");
+            // RabbitMQClient2.Instance.Conn("SpDataQueue");
+            // RabbitMQClient2.Instance.Conn("MainDataQueue");
             // 必须执行
         }
     }