
签名等所需要的加解密
- /// <summary>
- /// 解密类
- /// </summary>
- public class WxPayDecrypt
- {
- /// <summary>
- /// 解析密文
- /// </summary>
- /// <param name="associated_data"></param>
- /// <param name="nonce"></param>
- /// <param name="ciphertext"></param>
- /// <returns></returns>
- public static string GetAesGcmDecrypt(string associated_data, string nonce, string ciphertext)
- {
- return Encoding.UTF8.GetString(AesGcmDecrypt(associated_data, nonce, ciphertext,WxPayConfig.KEY));
- }
- /// <summary>
- /// AesGcm256解密
- /// </summary>
- /// <see cref="https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay4_2.shtml"/>
- /// <param name="associatedData"></param>
- /// <param name="nonce"></param>
- /// <param name="ciphertext"></param>
- /// <param name="aesKey"></param>
- /// <returns></returns>
- public static byte[] AesGcmDecrypt(string associatedData, string nonce, string ciphertext, string aesKey)
- {
- GcmBlockCipher gcmBlockCipher = new GcmBlockCipher(new AesEngine());
- AeadParameters aeadParameters = new AeadParameters(
- new KeyParameter(Encoding.UTF8.GetBytes(aesKey)),
- 128,
- Encoding.UTF8.GetBytes(nonce),
- Encoding.UTF8.GetBytes(associatedData));
- gcmBlockCipher.Init(false, aeadParameters);
- byte[] data = Convert.FromBase64String(ciphertext);
- byte[] plaintext = new byte[gcmBlockCipher.GetOutputSize(data.Length)];
- int length = gcmBlockCipher.ProcessBytes(data, 0, data.Length, plaintext, 0);
- gcmBlockCipher.DoFinal(plaintext, length);
- return plaintext;
- }
- /// <summary>
- /// AEAD_AES_256_GCM
- /// https://tools.ietf.org/html/rfc5116#page-15
- /// GCM加密后附加128位TAG形成密文
- /// </summary>
- /// <param name="key"></param>
- /// <returns></returns>
- public static byte[] Decrypt(string key, EncryptInfo encryptInfo)
- {
- var data = Convert.FromBase64String(encryptInfo.ciphertext);
- var cipher = data.AsEnumerable().Take(data.Length - 16).ToArray();
- var tag = data.AsEnumerable().Skip(data.Length - 16).ToArray();
- return AesGcmDecrypt(encryptInfo.associated_data, encryptInfo.nonce, encryptInfo.ciphertext, key);
- }
- }
- /// <summary>
- /// 加密类
- /// </summary>
- public static class WxPayEncrypt
- {
- /// <summary>
- /// 构造签名头
- /// </summary>
- /// <param name="url"></param>
- /// <param name="method"></param>
- /// <param name="body"></param>
- /// <param name="options"></param>
- /// <returns></returns>
- public static string BuildToken(string url, string method, string body, X509Certificate2 certificate, string merchantId)
- {
- string uri = string.Empty, nonce = string.Empty, message = string.Empty, signature = string.Empty, SerialNumber = string.Empty;
- try
- {
- uri = new Uri(url).PathAndQuery;
- long timestamp = WxPayUitls.GenerateTimeStamp();
- nonce = Guid.NewGuid().ToString("N");
- message = $"{method}\n{uri}\n{timestamp}\n{nonce}\n{body}\n";
- signature = message.ToRSAPrivateString(certificate);
- SerialNumber = certificate.SerialNumber;
- return $"mchid=\"{merchantId}\",nonce_str=\"{nonce}\",timestamp=\"{timestamp}\",serial_no=\"{SerialNumber}\",signature=\"{signature}\"";
- }
- catch (Exception ex)
- {
- Logger loger = LogManager.GetCurrentClassLogger();
- loger.Info("生成TOKEN失败 :" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss")
- + "\n message --> " + message + "--- SerialNumber --> " + SerialNumber
- + "\n" + ex.Message + "\n" + ex.StackTrace);
- throw;
- }
- }
- /// <summary>
- /// 调起支付生成签名
- /// </summary>
- /// <param name="request"></param>
- /// <returns></returns>
- public static string MakePaySign(string message)
- {
- try
- {
- X509Certificate2 Certificate = null;
- Certificate = new X509Certificate2(WxPayConfig.SSLCERT_PATH, WxPayConfig.SSLCERT_PASSWORD, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
- if (Certificate == null)
- {
- throw new WxPayException("证书获取失败");
- }
- return message.ToRSAPrivateString(Certificate);
- }
- catch (Exception e)
- {
- Logger loger = LogManager.GetCurrentClassLogger();
- loger.Error("调起支付生成签名异常:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "\r Message-->" + e.Message + "\r StackTrace--> " + e.StackTrace);
- throw;
- }
- }
- /// <summary>
- /// RSA 加密
- /// </summary>
- /// <param name="message">消息</param>
- /// <param name="certificate">证书</param>
- /// <returns></returns>
- private static string ToRSAPrivateString(this string message, X509Certificate2 certificate)
- {
- string signature = string.Empty;
- using (RSA rsa = certificate.GetRSAPrivateKey())
- {
- signature = Convert.ToBase64String(rsa.SignData(Encoding.UTF8.GetBytes(message), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1));
- }
- return signature;
- }
- /// <summary>
- /// 平台证书验签
- /// </summary>
- /// <param name="responseContent">响应原文</param>
- /// <param name="payHeader">请求头</param>
- /// <returns></returns>
- public static bool VerifySign(string responseContent, WechatPayHeader payHeader)
- {
- try
- {
- X509Certificate2 certificate = null;
- string pemPath = WxPayConfig.PLATEFORMSSLCERT_PATH + payHeader.SerialNo + ".pem";
- if (File.Exists(pemPath))
- {
- certificate = new X509Certificate2(pemPath, WxPayConfig.SSLCERT_APIV3KEY, X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
- }
- if (certificate == null)
- {
- certificate = WxPayApi.GetPlatformCertificate(payHeader.SerialNo);
- }
- string message = $"{payHeader.TimeStamp}\n{payHeader.Nonce}\n{responseContent}\n";
- using (var rsa = certificate.GetRSAPublicKey())
- {
- var res = rsa.VerifyData(Encoding.UTF8.GetBytes(message), Convert.FromBase64String(payHeader.Signature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
- return res;
- }
- }
- catch (Exception e)
- {
- Logger loger = LogManager.GetCurrentClassLogger();
- loger.Error("平台证书验签异常:" + DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss") + "\r Message-->" + e.Message + "\r StackTrace--> " + e.StackTrace);
- throw;
- }
- }
- }
评价
排名
63
文章
6
粉丝
2
评论
3
知识点----常用审核流程逻辑的梳理与设计
剑轩 : 很实用的知识!
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:
50010702506256


欢迎加群交流技术