分类:
微信支付
签名等所需要的加解密
/// <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; } } }
评价
排名
6
文章
6
粉丝
16
评论
8
{{item.articleTitle}}
{{item.blogName}} : {{item.content}}
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2024TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:50010702506256
欢迎加群交流技术