You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							659 lines
						
					
					
						
							29 KiB
						
					
					
				
			
		
		
	
	
							659 lines
						
					
					
						
							29 KiB
						
					
					
				using KGIS.Framework.Platform; | 
						|
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; | 
						|
 | 
						|
namespace Kingo.PluginServiceInterface | 
						|
{ | 
						|
    public static class EncryptionHelper | 
						|
    { | 
						|
        /// <summary> | 
						|
        /// 非对称加密私钥 | 
						|
        /// </summary> | 
						|
        //private static string PrvKeySM2 { get; set; } | 
						|
        /// <summary> | 
						|
        /// 非对称加密公钥 | 
						|
        /// </summary> | 
						|
        //private static string PubKeySM2 { get; set; } | 
						|
        private static string priKeySM2 = "3CD79D91480CF410148A2E8E1D8E5E8C534945F90E6CC92F43C92705112DC1AD"; | 
						|
        /// <summary> | 
						|
        /// 生成非对称加密秘钥 | 
						|
        /// </summary> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 生成对称加密秘钥 | 
						|
        /// </summary> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 非对称加密 | 
						|
        /// </summary> | 
						|
        /// <param name="txtWord"></param> | 
						|
        /// <param name="keyType">1:县级内网私钥加密  2:县级内网公钥加密  3:枢纽机公钥 </param> | 
						|
        /// <returns></returns> | 
						|
        public static string SM2Encrypt(string txtWord, int keyType, string xzqdm, bool isDog) | 
						|
        { | 
						|
            try | 
						|
            { | 
						|
                if (isDog) | 
						|
                { | 
						|
                    return SM2.Encrypt(GetDogKey(keyType, xzqdm), txtWord); | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    string pubk = SysConfigsOprator.GetAppsetingValueByKey("SM2PubK"); | 
						|
                    if (xzqdm.StartsWith("51") && Platform.Instance.SystemType == SystemTypeEnum.WYZS) | 
						|
                    { | 
						|
                        pubk = "04129C9C9E1FCA56B889B1D04BA2EC40194F69BCDE2BA2A32221C8A6E1CF78028550BBEDF3CECA7F505B3495340976E5AC90A5D84F61C74D04E27689E8A250B6703CA9EFC923182CA8426E4C529E51DFC08381E5AAC8D8C03E0B89CF233767BAECA6DC64EC3E0E86AE9462E92C9143FD2D977696DBE51E2D7D63E22F46E9257D0C82F26AE27053E90A83071F24C05ADE2ECA6B396AEE4AA057B45F901666DF76C4C9324BC7FFBF28FEB2236AD9B852D7A5C04474E8154FFE32431C2D3EB4EB020DA438D5E01211EE62D802B09058D538D350F1F1C62AE0870C98870B0CA81ED219767D"; | 
						|
                        return SM2.Encrypt(Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, pubk)), txtWord); | 
						|
                    } | 
						|
                    else if (Platform.Instance.SystemType == SystemTypeEnum.DTBJK && xzqdm.StartsWith("11")) | 
						|
                    { | 
						|
                        pubk = GetDogKey(2, xzqdm); | 
						|
                        return SM2.Encrypt(pubk, txtWord); | 
						|
                    } | 
						|
                    return SM2.Encrypt(Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, pubk)), txtWord); | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                LogAPI.Debug("非对称加密失败:" + ex.Message); | 
						|
                throw ex; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 非对称解密 | 
						|
        /// </summary> | 
						|
        public static string SM2Decrypt(string txtWord, string xzqdm, bool isDog) | 
						|
        { | 
						|
            try | 
						|
            { | 
						|
                if (isDog) | 
						|
                { | 
						|
                    return System.Text.Encoding.UTF8.GetString(SM2.Decrypt(GetDogKey(1, xzqdm), txtWord)); | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    return SM2.Encrypt(SysConfigsOprator.GetAppsetingValueByKey("SM2PriK"), txtWord); | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                LogAPI.Debug("非对称解密失败,请检查是否插入加密狗:" + ex.Message); | 
						|
                throw new Exception("请检查是否插入加密狗!"); | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 对称加密 | 
						|
        /// </summary> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 对称解密 | 
						|
        /// </summary> | 
						|
        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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 生成签章文件 | 
						|
        /// </summary> | 
						|
        /// <param name="dicPath"></param> | 
						|
        /// <param name="relativeFilePath"></param> | 
						|
        /// <param name="dataCode"></param> | 
						|
        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<string, string> keyVa = new Dictionary<string, string>(); | 
						|
                    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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 获取文件MD5 | 
						|
        /// </summary> | 
						|
        /// <param name="fileName">文件名</param> | 
						|
        /// <param name="isEncryption">是否加密</param> | 
						|
        /// <returns></returns> | 
						|
        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, FileShare.ReadWrite)) | 
						|
                { | 
						|
                    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; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 获取加密狗 | 
						|
        /// </summary> | 
						|
        /// <param name="keyType">1:内网私钥 2:内网公钥  3:枢纽机公钥</param> | 
						|
        /// <returns></returns> | 
						|
        public static string GetDogKey(int keyType, string xzqdm) | 
						|
        { | 
						|
            try | 
						|
            { | 
						|
                if (!string.IsNullOrWhiteSpace(xzqdm)) | 
						|
                { | 
						|
                    if (xzqdm.StartsWith("11") || xzqdm.StartsWith("51") || xzqdm.StartsWith("33")) | 
						|
                    { | 
						|
                        bool isSc = xzqdm.StartsWith("51"); | 
						|
                        bool isBj = xzqdm.StartsWith("11"); | 
						|
                        bool isZj = xzqdm.StartsWith("33"); | 
						|
                        switch (keyType) | 
						|
                        { | 
						|
                            case 1: | 
						|
                                if (isSc) | 
						|
                                { | 
						|
                                    return Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, "04129C9C9E1FCA56B889B1D04BA2EC40194F69BCDE2BA2A32221C8A6E1CF78028550BBEDF3CECA7F505B3495340976E5AC90A5D84F61C74D04E27689E8A250B6703DAE9DCD511F24DD32193C559A25DAB4F0F9E2ACCCD1C733088BBB554610BA9BDAD562ED4D7380DE9C6498589035F958E101E4A5906B5B0D62E12144EC500A7A0E39222B10663F92E3EFE154733F61AB893DDA94B7C5E46FD4FCB0B4CBA28469")); | 
						|
                                } | 
						|
                                else if (isBj) | 
						|
                                { | 
						|
                                    return Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, "04129C9C9E1FCA56B889B1D04BA2EC40194F69BCDE2BA2A32221C8A6E1CF78028550BBEDF3CECA7F505B3495340976E5AC90A5D84F61C74D04E27689E8A250B67048AF9ABE546E2CDA386F3852EE51DCB3868EE3DDC8D1CE327AFBBB273364C39DAEDC66EE4F05F1DD9010E52C97418157E07DE6DAE61C2C7E69EC20339D21780A512F4E5D28E2126BF0F0A61DF87F63D7646DB888FFE488094583F3695BBA4E91")); | 
						|
                                } | 
						|
                                else if (isZj) | 
						|
                                { | 
						|
                                    return Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, "04129C9C9E1FCA56B889B1D04BA2EC40194F69BCDE2BA2A32221C8A6E1CF78028550BBEDF3CECA7F505B3495340976E5AC90A5D84F61C74D04E27689E8A250B67039D8E8BD256B28DF401A4C529B53D5CD83FD9EA9B1D4C34208FBC9223664C09AAEAE649E397785D49314EC259748FC58907295A791682A7917E62E369F260D7C6A650F1F9AFB9897DDFE1DB5145D8A549205F6124CFA0E60C2251FD4A9393375")); | 
						|
                                } | 
						|
                                return KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SM2PriK"); | 
						|
                            case 2: | 
						|
                                if (isSc) | 
						|
                                { | 
						|
                                    return Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, "04129C9C9E1FCA56B889B1D04BA2EC40194F69BCDE2BA2A32221C8A6E1CF78028550BBEDF3CECA7F505B3495340976E5AC90A5D84F61C74D04E27689E8A250B6703CA9EFC923182CA8426E4C529E51DFC08381E5AAC8D8C03E0B89CF233767BAECA6DC64EC3E0E86AE9462E92C9143FD2D977696DBE51E2D7D63E22F46E9257D0C82F26AE27053E90A83071F24C05ADE2ECA6B396AEE4AA057B45F901666DF76C4C9324BC7FFBF28FEB2236AD9B852D7A5C04474E8154FFE32431C2D3EB4EB020DA438D5E01211EE62D802B09058D538D350F1F1C62AE0870C98870B0CA81ED219767D")); | 
						|
                                } | 
						|
                                else if (isBj) | 
						|
                                { | 
						|
                                    return Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, "04129C9C9E1FCA56B889B1D04BA2EC40194F69BCDE2BA2A32221C8A6E1CF78028550BBEDF3CECA7F505B3495340976E5AC90A5D84F61C74D04E27689E8A250B6703CA9E8C820692DDB376F30529551AEC4F0FC9EACBED9B43F098BCF2F3B60C0E8DDD964ED39778CA8E017992495408C5EE67596A7911E5978639227329954780EF5F51DED7421ED78F8086A23B32DDD53BC1C3D1A944DA757C42AE96F67A002C0CE3F4DB4F5C758F9B4551CD2BE20A5D4C733039963468B454A1C2D3EB3EB7F7DA2405730CA366CB749071E23A71348AE5BA7B3265809161F232A50AA6630E684255E")); | 
						|
                                } | 
						|
                                else if (isZj) | 
						|
                                { | 
						|
                                    return Encoding.UTF8.GetString(SM2.Decrypt(priKeySM2, "04129C9C9E1FCA56B889B1D04BA2EC40194F69BCDE2BA2A32221C8A6E1CF78028550BBEDF3CECA7F505B3495340976E5AC90A5D84F61C74D04E27689E8A250B6703CA9EECA501C5BD7406C3B22EA53D9CCF7FAE1DDCBD9B6417E8CC6204360C0EDA6A9179D3B0781ABE7149C5F9546892A9777EED6E51B5D7866E1263599227F7885871CE00454997A8B066B24B05BAE56BE68396A9B3CA525B22F951D1AA071B1CE4E38B288BB2A8DB45661D2BB51D0DFB4467CEA1135F435336B2A4CCD987F0DD337625452C5996886AEDAB72CE42E4C0BEB12E5867E578B824ED3738C07435F4476")); | 
						|
                                } | 
						|
                                return KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SM2PubK"); | 
						|
                            case 3: | 
						|
                                return KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SM2OutPubK"); | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
                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); | 
						|
                LogAPI.Debug(ex); | 
						|
            } | 
						|
            throw new Exception("获取加密狗异常"); | 
						|
            //return string.Empty; | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 验证基础库签章 | 
						|
        /// </summary> | 
						|
        /// <param name="jckPath"></param> | 
						|
        /// <returns></returns> | 
						|
        public static void CheckJCKSign(List<string> 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 = new string[1]; | 
						|
                    if (jckPath.EndsWith(".gdb", StringComparison.OrdinalIgnoreCase)) | 
						|
                    { | 
						|
                        files = System.IO.Directory.GetFiles(Directory.GetParent(jckPath)?.FullName, "*.sign", SearchOption.AllDirectories); | 
						|
                    } | 
						|
                    else | 
						|
                    { | 
						|
                        files = System.IO.Directory.GetFiles(jckPath, "*.sign", SearchOption.AllDirectories); | 
						|
                    } | 
						|
                    if (files == null || files.Length <= 0) | 
						|
                    { | 
						|
                        throw new Exception("请确认路径下签章是否存在:" + 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<string, string> JCDataList = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(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)) | 
						|
                            { | 
						|
                                throw new Exception(signPath + "签章校验不通过!"); | 
						|
                            } | 
						|
                        } | 
						|
                    } | 
						|
                } | 
						|
            } | 
						|
            catch (Exception ex) | 
						|
            { | 
						|
                throw ex; | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 验证基础库签章 | 
						|
        /// </summary> | 
						|
        /// <param name="lstPath">需要验证的路径列表</param> | 
						|
        /// <exception cref="Exception">验证失败时抛出异常</exception> | 
						|
        public static void SignatureVerification(List<string> lstPath) | 
						|
        { | 
						|
            string signKey = KGIS.Framework.Utils.SysConfigsOprator.GetAppsetingValueByKey("SignPubK"); | 
						|
            if (string.IsNullOrWhiteSpace(signKey)) | 
						|
            { | 
						|
                throw new Exception("未获取到SystemConfig.xml配置文件签章的公钥SignPubK!"); | 
						|
            } | 
						|
            ProjectInfo projectInfo = KGIS.Framework.Maps.MapsManager.Instance.MapService.GetProjectInfo() as ProjectInfo; | 
						|
            foreach (var jckPath in lstPath) | 
						|
            { | 
						|
                if (string.IsNullOrWhiteSpace(jckPath)) | 
						|
                { | 
						|
                    continue; | 
						|
                } | 
						|
                if (jckPath.EndsWith(".gdb", StringComparison.OrdinalIgnoreCase)) | 
						|
                { | 
						|
                    ValidateGdbSignatures(jckPath, signKey); | 
						|
                } | 
						|
                else if ((projectInfo.CODE ?? SysConfigsOprator.GetAppsetingValueByKey("ArearName")).StartsWith("51") && jckPath.Contains("影像")) | 
						|
                { | 
						|
                    ValidateImageSignatures(jckPath, signKey); | 
						|
                } | 
						|
                else | 
						|
                { | 
						|
                    ValidateRegularSignatures(jckPath, signKey); | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 验证GDB文件的签名 | 
						|
        /// </summary> | 
						|
        private static void ValidateGdbSignatures(string gdbPath, string signKey) | 
						|
        { | 
						|
            string parentDir = Directory.GetParent(gdbPath)?.FullName; | 
						|
            string[] signFiles = Directory.GetFiles(parentDir, "*.sign", SearchOption.AllDirectories); | 
						|
 | 
						|
            if (signFiles.Length == 0) | 
						|
            { | 
						|
                throw new Exception($"请确认路径下签章是否存在:{gdbPath}"); | 
						|
            } | 
						|
 | 
						|
            ValidateSingleSignature(signFiles[0], signKey, parentDir); | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 验证影像文件(.img/.tif)的签名 | 
						|
        /// </summary> | 
						|
        private static void ValidateImageSignatures(string imageDir, string signKey) | 
						|
        { | 
						|
            var imageFiles = Directory.EnumerateFiles(imageDir, "*.*", SearchOption.AllDirectories) | 
						|
                .Where(file => file.EndsWith(".img", StringComparison.OrdinalIgnoreCase) || | 
						|
                              file.EndsWith(".tif", StringComparison.OrdinalIgnoreCase)); | 
						|
 | 
						|
            foreach (string imagePath in imageFiles) | 
						|
            { | 
						|
                string signFilePath = Path.ChangeExtension(imagePath, ".sign"); | 
						|
 | 
						|
                if (!File.Exists(signFilePath)) | 
						|
                { | 
						|
                    throw new Exception($"请确认该签章文件存在:{signFilePath}"); | 
						|
                } | 
						|
 | 
						|
                string jckSign = CommonHelper.ReadTextFileConten(signFilePath); | 
						|
                if (string.IsNullOrWhiteSpace(jckSign)) | 
						|
                { | 
						|
                    throw new Exception($"{signFilePath}签章内容为空!"); | 
						|
                } | 
						|
 | 
						|
                var signatureData = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(jckSign); | 
						|
                if (signatureData == null || signatureData.Count == 0) | 
						|
                { | 
						|
                    continue; | 
						|
                } | 
						|
 | 
						|
                foreach (var item in signatureData) | 
						|
                { | 
						|
                    if (!File.Exists(imagePath)) | 
						|
                    { | 
						|
                        continue; | 
						|
                    } | 
						|
 | 
						|
                    string fileMd5 = GetMD5HashFromFile(imagePath, null, false); | 
						|
                    if (!SM2.Verify(fileMd5, item.Value, signKey)) | 
						|
                    { | 
						|
                        throw new Exception($"{signFilePath}签章校验不通过!"); | 
						|
                    } | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 验证常规签名文件 | 
						|
        /// </summary> | 
						|
        private static void ValidateRegularSignatures(string dirPath, string signKey) | 
						|
        { | 
						|
            string[] signFiles = Directory.GetFiles(dirPath, "*.sign", SearchOption.AllDirectories); | 
						|
 | 
						|
            if (signFiles.Length == 0) | 
						|
            { | 
						|
                throw new Exception($"请确认路径下签章是否存在:{dirPath}"); | 
						|
            } | 
						|
 | 
						|
            if (signFiles.Length > 1) | 
						|
            { | 
						|
                throw new Exception($"{dirPath}路径下有多个签章,无法验证签章!"); | 
						|
            } | 
						|
 | 
						|
            ValidateSingleSignature(signFiles[0], signKey, dirPath); | 
						|
        } | 
						|
 | 
						|
        /// <summary> | 
						|
        /// 验证单个签名文件 | 
						|
        /// </summary> | 
						|
        private static void ValidateSingleSignature(string signPath, string signKey, string baseDir) | 
						|
        { | 
						|
            string jckSign = CommonHelper.ReadTextFileConten(signPath); | 
						|
            if (string.IsNullOrWhiteSpace(jckSign)) | 
						|
            { | 
						|
                throw new Exception($"{signPath}签章内容为空!"); | 
						|
            } | 
						|
 | 
						|
            string[] gdbDirs = Directory.GetDirectories(Path.GetDirectoryName(signPath)) | 
						|
                .Where(x => x.EndsWith(".gdb", StringComparison.OrdinalIgnoreCase)) | 
						|
                .ToArray(); | 
						|
 | 
						|
            if (gdbDirs.Length == 0) | 
						|
            { | 
						|
                throw new Exception("同级文件夹下未找到省级下发基础库GDB!"); | 
						|
            } | 
						|
 | 
						|
            if (gdbDirs.Length > 1) | 
						|
            { | 
						|
                throw new Exception($"{signPath}签章同级文件夹下存在多个GDB,无法读取基础库!"); | 
						|
            } | 
						|
 | 
						|
            var signatureData = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string, string>>(jckSign); | 
						|
            if (signatureData == null || signatureData.Count == 0) | 
						|
            { | 
						|
                return; | 
						|
            } | 
						|
 | 
						|
            foreach (var item in signatureData) | 
						|
            { | 
						|
                string filePath = Path.Combine(gdbDirs[0], item.Key); | 
						|
                if (!File.Exists(filePath)) | 
						|
                { | 
						|
                    continue; | 
						|
                } | 
						|
 | 
						|
                string fileMd5 = GetMD5HashFromFile(filePath, null, false); | 
						|
                if (!SM2.Verify(fileMd5, item.Value, signKey)) | 
						|
                { | 
						|
                    throw new Exception($"{signPath}签章校验不通过!"); | 
						|
                } | 
						|
            } | 
						|
        } | 
						|
 | 
						|
 | 
						|
        /// <summary> | 
						|
        /// MD5加密 | 
						|
        /// </summary> | 
						|
        /// <param name="input">加密数据</param> | 
						|
        /// <returns>返回32位大写字符串</returns> | 
						|
        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(); | 
						|
        } | 
						|
    } | 
						|
}
 | 
						|
 |