Skip to content

Commit

Permalink
refactor: Adjusted the signature generation method to create signatur…
Browse files Browse the repository at this point in the history
…es for JS payment (V3).
  • Loading branch information
real-zony committed Jan 7, 2024
1 parent 6d6afbc commit 36a799c
Show file tree
Hide file tree
Showing 5 changed files with 25 additions and 16 deletions.
Original file line number Diff line number Diff line change
@@ -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]
Expand Down
11 changes: 11 additions & 0 deletions src/Pay/EasyAbp.Abp.WeChat.Pay/Security/CertificatesManager.cs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -36,6 +39,14 @@ public async Task<WeChatPayCertificate> 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<byte[]> GetX509CertificateBytesAsync(AbpWeChatPayOptions options)
{
if (options.CertificateBlobName.IsNullOrEmpty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,12 @@ public interface ICertificatesManager
/// <exception cref="ArgumentNullException">当证书的 BLOB 不存在时抛出此异常。</exception>
/// <exception cref="NullReferenceException">无法获取证书时会抛出此异常。</exception>
Task<WeChatPayCertificate> GetCertificateAsync(string mchId);

/// <summary>
/// 使用微信支付证书对待签名字符串进行签名。
/// </summary>
/// <param name="pendingSignature">等待签名的字符串。</param>
/// <param name="certificate">用于签名的证书实例。</param>
/// <returns>具体的签名数据,使用 Base64 编码。</returns>
string GetSignature(string pendingSignature, WeChatPayCertificate certificate);
}
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -21,7 +17,7 @@ public class WeChatPayAuthorizationGenerator : IWeChatPayAuthorizationGenerator,
/// 授权(Authorization)标头的认证类型。
/// </summary>
public const string AuthorizationScheme = "WECHATPAY2-SHA256-RSA2048";

private readonly IAbpWeChatPayOptionsProvider _weChatPayOptionsProvider;
private readonly ICertificatesManager _certificatesManager;

Expand All @@ -41,17 +37,9 @@ public async Task<string> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public sealed class WeChatPayCertificate
/// </summary>
/// <param name="mchId">商户号。</param>
/// <param name="certificateBytes">X509 证书实例。</param>
/// <param name="password">X509 证书的哈希值,用于快速比对证书是否发生变化。</param>
/// <param name="password">X509 证书的密码。</param>
public WeChatPayCertificate(string mchId, byte[] certificateBytes, string password)
{
MchId = mchId;
Expand Down

0 comments on commit 36a799c

Please sign in to comment.