From 36a799cbcb02331797c08704972701442821f667 Mon Sep 17 00:00:00 2001 From: real-zony Date: Sun, 7 Jan 2024 20:41:55 +0800 Subject: [PATCH] refactor: Adjusted the signature generation method to create signatures for JS payment (V3). --- .../Dtos/GetJsSdkWeChatPayParametersInput.cs | 2 ++ .../Security/CertificatesManager.cs | 11 +++++++++++ .../Security/ICertificatesManager.cs | 8 ++++++++ .../WeChatPayAuthorizationGenerator.cs | 18 +++--------------- .../Security/WeChatPayCertificate.cs | 2 +- 5 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/Pay/EasyAbp.Abp.WeChat.Pay.Abstractions/RequestHandling/Dtos/GetJsSdkWeChatPayParametersInput.cs b/src/Pay/EasyAbp.Abp.WeChat.Pay.Abstractions/RequestHandling/Dtos/GetJsSdkWeChatPayParametersInput.cs index e90a751..578c009 100644 --- a/src/Pay/EasyAbp.Abp.WeChat.Pay.Abstractions/RequestHandling/Dtos/GetJsSdkWeChatPayParametersInput.cs +++ b/src/Pay/EasyAbp.Abp.WeChat.Pay.Abstractions/RequestHandling/Dtos/GetJsSdkWeChatPayParametersInput.cs @@ -1,11 +1,13 @@ using System; using System.ComponentModel.DataAnnotations; +using JetBrains.Annotations; namespace EasyAbp.Abp.WeChat.Pay.RequestHandling.Dtos; [Serializable] public class GetJsSdkWeChatPayParametersInput { + [CanBeNull] public string MchId { get; set; } [Required] diff --git a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/CertificatesManager.cs b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/CertificatesManager.cs index d7bd59f..45495bc 100644 --- a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/CertificatesManager.cs +++ b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/CertificatesManager.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Concurrent; +using System.Security.Cryptography; +using System.Security.Cryptography.X509Certificates; +using System.Text; using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Pay.Options; using Volo.Abp.BlobStoring; @@ -36,6 +39,14 @@ public async Task GetCertificateAsync(string mchId) new WeChatPayCertificate(options.MchId, certificateBytes, options.CertificateSecret))).Value; } + public string GetSignature(string pendingSignature, WeChatPayCertificate certificate) + { + var privateKey = certificate.X509Certificate.GetRSAPrivateKey(); + var signDataBytes = privateKey.SignData(Encoding.UTF8.GetBytes(pendingSignature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); + + return Convert.ToBase64String(signDataBytes); + } + protected virtual async Task GetX509CertificateBytesAsync(AbpWeChatPayOptions options) { if (options.CertificateBlobName.IsNullOrEmpty()) diff --git a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/ICertificatesManager.cs b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/ICertificatesManager.cs index 4346b02..ed3e3a2 100644 --- a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/ICertificatesManager.cs +++ b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/ICertificatesManager.cs @@ -16,4 +16,12 @@ public interface ICertificatesManager /// 当证书的 BLOB 不存在时抛出此异常。 /// 无法获取证书时会抛出此异常。 Task GetCertificateAsync(string mchId); + + /// + /// 使用微信支付证书对待签名字符串进行签名。 + /// + /// 等待签名的字符串。 + /// 用于签名的证书实例。 + /// 具体的签名数据,使用 Base64 编码。 + string GetSignature(string pendingSignature, WeChatPayCertificate certificate); } \ No newline at end of file diff --git a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayAuthorizationGenerator.cs b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayAuthorizationGenerator.cs index cde9743..ee75893 100644 --- a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayAuthorizationGenerator.cs +++ b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayAuthorizationGenerator.cs @@ -1,8 +1,4 @@ -using System; -using System.Net.Http; -using System.Security.Cryptography; -using System.Security.Cryptography.X509Certificates; -using System.Text; +using System.Net.Http; using System.Threading.Tasks; using EasyAbp.Abp.WeChat.Common.Extensions; using EasyAbp.Abp.WeChat.Pay.ApiRequests; @@ -21,7 +17,7 @@ public class WeChatPayAuthorizationGenerator : IWeChatPayAuthorizationGenerator, /// 授权(Authorization)标头的认证类型。 /// public const string AuthorizationScheme = "WECHATPAY2-SHA256-RSA2048"; - + private readonly IAbpWeChatPayOptionsProvider _weChatPayOptionsProvider; private readonly ICertificatesManager _certificatesManager; @@ -41,17 +37,9 @@ public async Task GenerateAuthorizationAsync(HttpMethod method, string u var requestModel = new WeChatPayApiRequestModel(method, url, body, timeStamp, nonceStr); var pendingSignature = requestModel.GetPendingSignatureString(); var certificate = await _certificatesManager.GetCertificateAsync(mchId); - var signString = RsaSign(pendingSignature, certificate); + var signString = _certificatesManager.GetSignature(pendingSignature, certificate); return $"{AuthorizationScheme} mchid=\"{options.MchId}\",nonce_str=\"{nonceStr}\",timestamp=\"{timeStamp}\",serial_no=\"{certificate.X509Certificate.SerialNumber}\",signature=\"{signString}\""; } - - private string RsaSign(string pendingSignature, WeChatPayCertificate certificate) - { - var privateKey = certificate.X509Certificate.GetRSAPrivateKey(); - var signDataBytes = privateKey.SignData(Encoding.UTF8.GetBytes(pendingSignature), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); - - return Convert.ToBase64String(signDataBytes); - } } \ No newline at end of file diff --git a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayCertificate.cs b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayCertificate.cs index 0430071..56fe601 100644 --- a/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayCertificate.cs +++ b/src/Pay/EasyAbp.Abp.WeChat.Pay/Security/WeChatPayCertificate.cs @@ -28,7 +28,7 @@ public sealed class WeChatPayCertificate /// /// 商户号。 /// X509 证书实例。 - /// X509 证书的哈希值,用于快速比对证书是否发生变化。 + /// X509 证书的密码。 public WeChatPayCertificate(string mchId, byte[] certificateBytes, string password) { MchId = mchId;