using KGIS.Framework.Utils; using Kingo.Crypto; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace Kingo.PluginServiceInterface { public static class EncryptionHelper { /// /// 非对称加密私钥 /// //private static string PrvKeySM2 { get; set; } /// /// 非对称加密公钥 /// //private static string PubKeySM2 { get; set; } /// /// 生成非对称加密秘钥 /// public static void GenerKeySM2() { try { string prvKey = string.Empty; string pubKey = string.Empty; SM2.GenerateKeyPair(out prvKey, out pubKey); using (StreamWriter writer = new StreamWriter("PrivateKey_SM2.xml")) //这个文件要保密 { writer.WriteLine(prvKey); } using (StreamWriter writer = new StreamWriter("PublicKey_SM2.xml")) { writer.WriteLine(pubKey); } } catch (Exception ex) { LogAPI.Debug(ex); throw ex; } } /// /// 生成对称加密秘钥 /// public static string GenerKeySM4() { try { SM4 sm4 = new SM4(); //生成秘钥 return sm4.GenerateKey(); //using (StreamWriter writer = new StreamWriter("PrivateKey_SM4.xml")) //这个文件要保密 //{ // writer.WriteLine(PrvKeySM4); //} } catch (Exception ex) { throw ex; } } /// /// 非对称加密 /// /// /// 1:县级内网私钥加密 2:县级内网公钥加密 3:枢纽机公钥 /// public static string SM2Encrypt(string txtWord, int keyType, string xzqdm) { try { return SM2.Encrypt(GetDogKey(keyType, xzqdm), txtWord); } catch (Exception ex) { LogAPI.Debug("非对称加密失败:" + ex.Message); throw ex; } } /// /// 非对称解密 /// public static string SM2Decrypt(string txtWord, string xzqdm) { try { return System.Text.Encoding.UTF8.GetString(SM2.Decrypt(GetDogKey(1, xzqdm), txtWord)); } catch (Exception ex) { LogAPI.Debug("非对称解密失败,请检查是否插入加密狗:" + ex.Message); throw new Exception("请检查是否插入加密狗!"); } } /// /// 对称加密 /// public static string SM4Encrypt(string txtWord, string key) { try { SM4 sm4 = new SM4(); sm4.secretKey = key; sm4.hexString = true; return sm4.EncryptECB(txtWord); } catch (Exception ex) { LogAPI.Debug("对称加密失败:" + ex.Message); throw ex; } } /// /// 对称解密 /// public static string SM4Decrypt(string txtWord, string key) { try { SM4 sm4 = new SM4(); sm4.secretKey = key; sm4.hexString = true; return sm4.DecryptECB(txtWord); } catch (Exception ex) { LogAPI.Debug("对称解密失败:" + ex.Message); throw ex; } } /// /// 生成签章文件 /// /// /// /// public static string GetFileSing(string filePath, string xzqdm, string dataCode = "") { try { if (dataCode.ToUpper() == "SHP") { string shpFileMd5 = GetMD5HashFromFile(filePath, xzqdm); string fileName = System.IO.Path.GetFileNameWithoutExtension(filePath); string dbfFilePath = System.IO.Path.GetDirectoryName(filePath) + "\\" + fileName + ".dbf"; string dbfFileMd5 = GetMD5HashFromFile(dbfFilePath, xzqdm); return shpFileMd5 + dbfFileMd5; //string signContent = Kingo.Crypto.SM2.Sm2Sign(shpFileMd5 + dbfFileMd5, PrvKeySM2); //string signFilePath = System.IO.Path.GetDirectoryName(filePath) + "\\" + fileName + ".sign"; //StreamWriter streamWriter = File.CreateText(signFilePath); //streamWriter.Write(signContent); //streamWriter.Close(); } else if (dataCode.ToUpper() == "GDB") { string[] files = System.IO.Directory.GetFiles(filePath, "*.*", SearchOption.AllDirectories); Dictionary keyVa = new Dictionary(); foreach (string item in files) { string fileName = System.IO.Path.GetFileName(item); if (System.IO.Path.GetExtension(item).Equals(".lock", StringComparison.CurrentCultureIgnoreCase) || System.IO.Path.GetExtension(item).Equals(".xls", StringComparison.CurrentCultureIgnoreCase) || System.IO.Path.GetExtension(item).Equals(".xlsx", StringComparison.CurrentCultureIgnoreCase)) { continue; } string fileMd5 = GetMD5HashFromFile(item, xzqdm); if (string.IsNullOrWhiteSpace(fileMd5)) { continue; } keyVa.Add(fileName, fileMd5); } return Newtonsoft.Json.JsonConvert.SerializeObject(keyVa); } else { return GetMD5HashFromFile(filePath, xzqdm); } } catch (Exception ex) { throw ex; } } public static bool CreateSign(string json, string signFileName) { try { try { if (System.IO.File.Exists(signFileName)) { System.IO.File.Delete(signFileName); } } catch (Exception ex) { LogAPI.Debug("删除已有签章失败:" + ex.Message); } //string signContent = Kingo.Crypto.SM2.Sm2Sign(json, PrvKeySM2); using (StreamWriter streamWriter = File.CreateText(signFileName)) { streamWriter.Write(json); streamWriter.Close(); } return true; } catch (Exception ex) { throw ex; } } /// /// 获取文件MD5 /// /// 文件名 /// 是否加密 /// public static string GetMD5HashFromFile(string fileName, string xzqdm, bool isEncryption = true) { try { //System.Security.Cryptography.MD5 md5Hasher = System.Security.Cryptography.MD5.Create(); //byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(fileName)); //StringBuilder sBuilder = new StringBuilder(); //for (int i = 0; i < data.Length; i++) //{ // sBuilder.Append(data[i].ToString("x2")); //} //return Kingo.Crypto.SM2.Sm2Sign(sBuilder.ToString(), key); using (FileStream file = new FileStream(fileName, FileMode.Open, FileAccess.Read)) { System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); byte[] retVal = md5.ComputeHash(file); StringBuilder sb = new StringBuilder(); for (int i = 0; i < retVal.Length; i++) { sb.Append(retVal[i].ToString("x2")); } if (isEncryption) { return Kingo.Crypto.SM2.Sm2Sign(sb.ToString(), GetDogKey(1, xzqdm)); } else { return sb.ToString(); } } } catch (Exception ex) { LogAPI.Debug("获取文件md5失败:" + ex.Message); return null; } } /// /// 获取加密狗 /// /// 1:内网私钥 2:内网公钥 3:枢纽机公钥 /// public static string GetDogKey(int keyType, string xzqdm) { try { KGIS.USBDog.USBKey uSBKey = KGIS.USBDog.Dog.GetDogContent(); if (uSBKey == null) { string dogKey = KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("TestKey"); if (!string.IsNullOrWhiteSpace(dogKey) && dogKey.Equals("kingo")) { switch (keyType) { case 1: return KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SM2PriK"); case 2: return KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SM2PubK"); case 3: return KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SM2OutPubK"); } } } else { if (uSBKey.Xzqdm.EndsWith("0000"))//省级加密狗 { } else if (uSBKey.Xzqdm.EndsWith("00") && xzqdm.StartsWith(uSBKey.Xzqdm.Substring(0, 4)))//市级加密狗 { } else if (uSBKey.Type != 2 || !uSBKey.Xzqdm.Equals(xzqdm)) //uSBKey.Type = 2 县级内网加密狗 { //LogAPI.Debug($"获取到的加密狗不是{xzqdm}县内网加密狗!"); return string.Empty; } switch (keyType) { case 1: return uSBKey.SelfPrivateKey; case 2: return uSBKey.SelfPublicKey; case 3: return uSBKey.PublicKey; } } } catch (Exception ex) { LogAPI.Debug("获取加密狗异常:" + ex.Message); } throw new Exception("获取加密狗异常"); //return string.Empty; } /// /// 验证基础库签章 /// /// /// public static void CheckJCKSign(List lstPath) { try { string signKey = KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SignPubK"); if (string.IsNullOrWhiteSpace(signKey)) { throw new Exception("未获取到SystemConfig.xml配置文件签章的公钥SignPubK!"); } foreach (var jckPath in lstPath) { string[] files = System.IO.Directory.GetFiles(jckPath, "*.sign", SearchOption.AllDirectories); if (files == null || files.Length <= 0) { throw new Exception("请确认路径下签章是否存在:" + jckPath); //MessageHelper.ShowError("请确认路径下签章是否存在:" + jckPath); } if (files.Length > 1) { throw new Exception(jckPath + "路径下有多个签章,无法验证签章!"); } string signPath = files[0]; string jckSign = CommonHelper.ReadTextFileConten(signPath); if (string.IsNullOrWhiteSpace(jckSign)) { throw new Exception(signPath + "签章内容为空!"); } string[] dirs = System.IO.Directory.GetDirectories(System.IO.Path.GetDirectoryName(signPath)); if (dirs == null || dirs.Length <= 0) { throw new Exception("同级文件夹下未找到省级下发基础库GDB!"); } string gdbPath = dirs[0]; if (dirs.Length > 1 && dirs.Where(x => x.EndsWith(".gdb", StringComparison.CurrentCultureIgnoreCase)).Count() > 1) { throw new Exception(signPath + "签章同级文件夹下存在多个GDB,无法读取基础库!"); } gdbPath = dirs.FirstOrDefault(x => x.EndsWith(".gdb", StringComparison.CurrentCultureIgnoreCase)); Dictionary JCDataList = Newtonsoft.Json.JsonConvert.DeserializeObject>(jckSign); if (JCDataList != null && JCDataList.Count > 0) { string filePath = string.Empty; foreach (var item in JCDataList) { filePath = System.IO.Path.Combine(gdbPath, item.Key); if (!System.IO.File.Exists(filePath)) { continue; } string fileMd5 = GetMD5HashFromFile(filePath, null, false); if (!SM2.Verify(fileMd5, item.Value, signKey)) { //MessageHelper.ShowError(signPath + "签章校验不通过!"); throw new Exception(signPath + "签章校验不通过!"); } } } } } catch (Exception ex) { throw ex; //MessageHelper.ShowError(ex.Message); } } /// /// MD5加密 /// /// 加密数据 /// 返回32位大写字符串 public static string GetMd5Hash(string input) { byte[] inputBytes = Encoding.UTF8.GetBytes(input); MD5 md5 = MD5.Create(); byte[] hashBytes = md5.ComputeHash(inputBytes); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < hashBytes.Length; i++) { stringBuilder.Append(hashBytes[i].ToString("X2")); } return stringBuilder.ToString(); } } }