SignatureAndVerification.cs 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.IO;
  5. using System.Security.Cryptography;
  6. using System.Security.Cryptography.X509Certificates;
  7. using System.Text;
  8. namespace Utils
  9. {
  10. public class SignatureAndVerification
  11. {
  12. /// <summary>
  13. /// nlog日志
  14. /// </summary>
  15. private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
  16. public static string keystore_password = AppSettingsHelper.Configuration["NHBridge:keystore_password"];
  17. public static string PrivateKeyPath = AppSettingsHelper.Configuration["NHBridge:PrivateKeyPath"];
  18. public static string PublicKeyPath = AppSettingsHelper.Configuration["NHBridge:PublicKeyPath"];
  19. /// <summary>
  20. /// 接收报文返回requsetBody和使用base64解析后的requsetBody以及缴费中心传送的签名
  21. /// </summary>
  22. /// <param name="request">请求报文</param>
  23. /// <returns></returns>
  24. public Dictionary<string, string> requestBodyOfBase64(string request)
  25. {
  26. logger.Info($"收到的报文:{request}");
  27. Dictionary<string, string> requestMap = new Dictionary<string, string>
  28. {
  29. //使用base64解析完成后的requsetBody
  30. { "requsetBodyOfDecoded", "" },
  31. //解析前的requsetBody
  32. { "requsetBody", "" },
  33. //获取缴费中心传送过来的签名
  34. { "signatureString", "" }
  35. };
  36. try
  37. {
  38. string signatureString = request.Substring(0, request.IndexOf("||"));
  39. string requsetBody = request.Substring(signatureString.Length + 2);
  40. string requsetBodyOfDecoded = Base64Util.DecodeData(requsetBody);
  41. logger.Info($"加签串:{signatureString},base64加密报文:{requsetBody},解密的报文:{requsetBodyOfDecoded}");
  42. if (!string.IsNullOrWhiteSpace(signatureString) && !string.IsNullOrWhiteSpace(requsetBody) && !string.IsNullOrWhiteSpace(requsetBodyOfDecoded))
  43. {
  44. requestMap["requsetBodyOfDecoded"] = requsetBodyOfDecoded;
  45. requestMap["requsetBody"] = requsetBody;
  46. requestMap["signatureString"] = signatureString;
  47. }
  48. else
  49. {
  50. logger.Error("非正常格式请求报文,请检查报文并联系发送方。");
  51. }
  52. }
  53. catch (Exception e)
  54. {
  55. logger.Error($"解析报文信息异常,报错信息:{e.Message},报错堆栈:{e.StackTrace}");
  56. }
  57. return requestMap;
  58. }
  59. /// <summary>
  60. /// 解析报文,验证签名
  61. /// </summary>
  62. /// <param name="requestMap"></param>
  63. /// <returns></returns>
  64. public string verify_sign(Dictionary<string, string> requestMap)
  65. {
  66. //使用base64解析完成后的requsetBody
  67. string requsetBodyOfDecoded = requestMap["requsetBodyOfDecoded"];
  68. //解析前的requsetBody
  69. string requsetBody = requestMap["requsetBody"];
  70. //获取缴费中心传送过来的签名
  71. string signatureString = requestMap["signatureString"];
  72. //报文解析错误处理
  73. if (string.IsNullOrWhiteSpace(signatureString))
  74. {
  75. logger.Error("解析报文出错");
  76. return "";
  77. }
  78. //验签
  79. bool sign = read_cer_and_verify_sign(requsetBody, signatureString);
  80. //如果验签失败,处理
  81. //if (!sign) {
  82. //}
  83. return requsetBodyOfDecoded;
  84. }
  85. /// <summary>
  86. /// 读取cer并验证公钥签名
  87. /// </summary>
  88. /// <param name="requsetBody">json报文数据</param>
  89. /// <param name="signature">加签标识</param>
  90. /// <returns>成功:true,失败:false</returns>
  91. public bool read_cer_and_verify_sign(string requsetBody, string signature)
  92. {
  93. bool result = false;
  94. try
  95. {
  96. byte[] orgin = Encoding.UTF8.GetBytes((requsetBody));//json报文数据获得字节数据
  97. byte[] singedBase64 = Convert.FromBase64String((signature));//对加签部分进行base64解密操作
  98. RSACryptoServiceProvider tMerchantKey = GetPublicKey();//读取证书
  99. result = tMerchantKey.VerifyData(orgin, "SHA1", singedBase64);
  100. logger.Info($"验证签名的加签串:{signature},签名验证结果:{result}");
  101. return result;
  102. }
  103. catch (Exception ex)
  104. {
  105. logger.Error(ex, "验签失败!");
  106. return result;
  107. }
  108. }
  109. /// <summary>
  110. /// 加签名
  111. /// </summary>
  112. /// <param name="contentForSign">需加标签的字符串</param>
  113. /// <returns></returns>
  114. public string signWhithsha1withrsa(string contentForSign)
  115. {
  116. string result = "";
  117. try
  118. {
  119. //string filePath = rootPath + PFXPATH;
  120. //获取私钥
  121. RSACryptoServiceProvider tMerchantKey = GetPrivateKey();
  122. SHA1Managed tHash = new SHA1Managed();
  123. //将传递需要加签的字符串进行base64操作
  124. byte[] base64 = Encoding.UTF8.GetBytes(Convert.ToBase64String(Encoding.UTF8.GetBytes(contentForSign)));
  125. byte[] tHashedData = tHash.ComputeHash(base64);
  126. //对其进行加签名
  127. byte[] tSigned = tMerchantKey.SignHash(tHashedData, "SHA1");
  128. result = Convert.ToBase64String(tSigned);
  129. return result;
  130. }
  131. catch (Exception ex)
  132. {
  133. logger.Error(ex, "加签失败!");
  134. return result;
  135. }
  136. }
  137. /// <summary>
  138. /// 获取返回报文数据,加签名及加密
  139. /// </summary>
  140. /// <param name="json"></param>
  141. /// <returns></returns>
  142. public string GetResponseJson(string json)
  143. {
  144. logger.Info("查询结果原始报文数据:" + json);
  145. // 加签名以及加密
  146. string signatrue = signWhithsha1withrsa(json);
  147. string responseJson = signatrue + "||" + Base64Util.EncodeData(json);
  148. logger.Info("查询结果返回报文数据(报文加签且base64加密后):" + responseJson);
  149. return responseJson;
  150. }
  151. /// <summary>
  152. /// 获取私钥
  153. /// </summary>
  154. /// <returns></returns>
  155. private static RSACryptoServiceProvider GetPrivateKey()
  156. {
  157. try
  158. {
  159. //以读取路径的方式读取文件 path为存放证书路径
  160. var cer = new X509Certificate2(File.ReadAllBytes(PrivateKeyPath), keystore_password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
  161. //byte[] rawData = Resource._103881104410001;
  162. //byte[] rawData = returnbyte("d://103881104410001.pfx");
  163. //string file = "d://103881104410001.pfx";
  164. //var cer = new X509Certificate2(rawData, Resource.keystore_password, X509KeyStorageFlags.Exportable | X509KeyStorageFlags.MachineKeySet);
  165. return (RSACryptoServiceProvider)cer.PrivateKey;
  166. }
  167. catch { throw; }
  168. }
  169. /// <summary>
  170. /// 获取公钥
  171. /// </summary>
  172. /// <returns></returns>
  173. private static RSACryptoServiceProvider GetPublicKey()
  174. {
  175. try
  176. {
  177. //以读取路径的方式读取文件 path为存放证书路径
  178. var cer = new X509Certificate2(File.ReadAllBytes(PublicKeyPath));
  179. //var cer = new X509Certificate2(Resource.TrustPayTest);
  180. return (RSACryptoServiceProvider)cer.PublicKey.Key;
  181. }
  182. catch { throw; }
  183. }
  184. }
  185. }