|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 非对称加密私钥
|
|
|
|
|
/// </summary>
|
|
|
|
|
//private static string PrvKeySM2 { get; set; }
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 非对称加密公钥
|
|
|
|
|
/// </summary>
|
|
|
|
|
//private static string PubKeySM2 { get; set; }
|
|
|
|
|
|
|
|
|
|
/// <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)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
return SM2.Encrypt(GetDogKey(keyType, xzqdm), txtWord);
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
LogAPI.Debug("非对称加密失败:" + ex.Message);
|
|
|
|
|
throw ex;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 非对称解密
|
|
|
|
|
/// </summary>
|
|
|
|
|
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("请检查是否插入加密狗!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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))
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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 = 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<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))
|
|
|
|
|
{
|
|
|
|
|
//MessageHelper.ShowError(signPath + "签章校验不通过!");
|
|
|
|
|
throw new Exception(signPath + "签章校验不通过!");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
throw ex;
|
|
|
|
|
//MessageHelper.ShowError(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <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();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|