diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Exceptions/WechatTenpayRequestEncryptionException.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Exceptions/WechatTenpayRequestEncryptionException.cs
new file mode 100644
index 00000000..411f7f4e
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Exceptions/WechatTenpayRequestEncryptionException.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Exceptions
+{
+ public class WechatTenpayRequestEncryptionException : WechatTenpayException
+ {
+ ///
+ internal WechatTenpayRequestEncryptionException()
+ {
+ }
+
+ ///
+ internal WechatTenpayRequestEncryptionException(string message)
+ : base(message)
+ {
+ }
+
+ ///
+ internal WechatTenpayRequestEncryptionException(string message, Exception innerException)
+ : base(message, innerException)
+ {
+ }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventVerificationExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventVerificationExtensions.cs
index fcb06151..534b2eac 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventVerificationExtensions.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientEventVerificationExtensions.cs
@@ -65,7 +65,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
- var cert = client.CertificateManager.GetEntry(callbackSerialNumber)!;
+ var cert = client.CertificateManager.GetEntry(callbackSerialNumber);
if (!cert.HasValue)
{
error = new Exceptions.WechatTenpayEventVerificationException("Verify signature of event failed, because there is no platform certificate matched the serial number.");
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientRequestEncryptionExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientRequestEncryptionExtensions.cs
new file mode 100644
index 00000000..e52da044
--- /dev/null
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientRequestEncryptionExtensions.cs
@@ -0,0 +1,82 @@
+using System;
+using System.Linq;
+using System.Reflection;
+
+namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
+{
+ ///
+ /// 为 提供请求模型敏感数据加密的扩展方法。
+ ///
+ public static class WechatTenpayClientRequestEncryptionExtensions
+ {
+ ///
+ /// 加密请求中传入的敏感数据。该方法会改变传入的请求模型对象。
+ ///
+ ///
+ ///
+ ///
+ public static TRequest EncryptRequestSensitiveProperty(this WechatTenpayClient client, TRequest request)
+ where TRequest : WechatTenpayRequest
+ {
+ if (client == null) throw new ArgumentNullException(nameof(client));
+ if (request == null) throw new ArgumentNullException(nameof(request));
+
+ try
+ {
+ // 遍历并加密被标记为敏感数据的字段
+ Utilities.ReflectionUtility.ReplacePropertyStringValue(ref request, (obj, prop, value) =>
+ {
+ var attr = prop.GetCustomAttribute();
+ if (attr == null)
+ return value;
+
+ if (Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB.Equals(attr.Algorithm))
+ {
+ if (client.CertificateManager == null)
+ throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed, because there is no platform certificate in the manager.");
+
+ string certificate;
+
+ if (!string.IsNullOrEmpty(request.WechatpayCertSerialNumber))
+ {
+ // 如果已在请求中指定特定的平台证书序列号,直接从管理器中取值
+ var cert = client.CertificateManager.GetEntry(request.WechatpayCertSerialNumber!);
+ if (!cert.HasValue)
+ {
+ throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate matched the serial number.");
+ }
+
+ certificate = cert.Value.Certificate;
+ }
+ else
+ {
+ // 如果未在请求中指定特定的平台证书序列号,从管理器中取过期时间最远的
+ var certs = client.CertificateManager.AllEntries().OrderByDescending(e => e.ExpireTime);
+ if (!certs.Any())
+ {
+ throw new Exceptions.WechatTenpayEventVerificationException("Encrypt request failed, because there is no platform certificate in the manager.");
+ }
+
+ certificate = certs.First().Certificate;
+ }
+
+ return Utilities.RSAUtility.EncryptWithECBByCertificate(
+ certificate: certificate,
+ plainText: value
+ );
+ }
+ else
+ {
+ throw new Exceptions.WechatTenpayRequestEncryptionException("Unsupported encryption algorithm.");
+ }
+ });
+ }
+ catch (Exception ex) when (!(ex is Exceptions.WechatTenpayRequestEncryptionException))
+ {
+ throw new Exceptions.WechatTenpayRequestEncryptionException("Encrypt request failed. Please see the `InnerException` for more details.", ex);
+ }
+
+ return request;
+ }
+ }
+}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs
index 34cf3967..25b96692 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientResponseDecryptionExtensions.cs
@@ -1,17 +1,15 @@
using System;
-using System.Collections.Generic;
-using System.Linq;
using System.Reflection;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
///
- /// 为 提供响应敏感数据解密的扩展方法。
+ /// 为 提供响应模型敏感数据解密的扩展方法。
///
public static class WechatTenpayClientResponseDecryptionExtensions
{
///
- /// 解密响应中返回的敏感数据。该方法会改变传入的响应信息。
+ /// 解密响应中返回的敏感数据。该方法会改变传入的响应模型对象。
///
///
///
@@ -22,9 +20,6 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
if (client == null) throw new ArgumentNullException(nameof(client));
if (response == null) throw new ArgumentNullException(nameof(response));
- if (string.IsNullOrEmpty(client.Credentials.MerchantCertPrivateKey))
- throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because there is no merchant private key.");
-
if (!response.IsSuccessful())
throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because the response is not successful.");
@@ -40,6 +35,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
if (Constants.EncryptionAlgorithms.AEAD_AES_256_GCM.Equals(certificateModel.EncryptCertificate?.Algorithm))
{
+ if (string.IsNullOrEmpty(client.Credentials.MerchantCertPrivateKey))
+ throw new Exceptions.WechatTenpayResponseDecryptionException("Decrypt response failed, because there is no merchant private key.");
+
certificateModel.EncryptCertificate.CipherText = Utilities.AESUtility.DecryptWithGCM(
key: client.Credentials.MerchantV3Secret,
iv: certificateModel.EncryptCertificate.Nonce,
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs
index 9e173dec..cdf673a5 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/CreateApplyForSubMerchantApplymentRequest.cs
@@ -17,6 +17,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("contact_name")]
[System.Text.Json.Serialization.JsonPropertyName("contact_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string Name { get; set; } = string.Empty;
///
@@ -24,6 +25,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("mobile_phone")]
[System.Text.Json.Serialization.JsonPropertyName("mobile_phone")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string Mobile { get; set; } = string.Empty;
///
@@ -31,6 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("contact_id_number")]
[System.Text.Json.Serialization.JsonPropertyName("contact_id_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? IdCardNumber { get; set; }
///
@@ -45,6 +48,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("contact_email")]
[System.Text.Json.Serialization.JsonPropertyName("contact_email")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string Email { get; set; } = string.Empty;
}
@@ -198,6 +202,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_card_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdCardName { get; set; } = string.Empty;
///
@@ -205,6 +210,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdCardNumber { get; set; } = string.Empty;
///
@@ -236,6 +242,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_doc_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdDocumentName { get; set; } = string.Empty;
///
@@ -243,6 +250,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_doc_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdDocumentNumber { get; set; } = string.Empty;
///
@@ -325,6 +333,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string Name { get; set; } = string.Empty;
///
@@ -332,6 +341,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdNumber { get; set; } = string.Empty;
///
@@ -708,6 +718,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("account_name")]
[System.Text.Json.Serialization.JsonPropertyName("account_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string AccountName { get; set; } = string.Empty;
///
@@ -715,6 +726,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("account_number")]
[System.Text.Json.Serialization.JsonPropertyName("account_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string AccountNumber { get; set; } = string.Empty;
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs
index a20b32c7..f6cb7dab 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4SubMerchant/Settlement/ModifyApplyForSubMerchantSettlementRequest.cs
@@ -27,6 +27,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("account_number")]
[System.Text.Json.Serialization.JsonPropertyName("account_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string AccountNumber { get; set; } = string.Empty;
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4Subject/CreateApplyForSubjectApplymentRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4Subject/CreateApplyForSubjectApplymentRequest.cs
index 4ec44317..4598bcd7 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4Subject/CreateApplyForSubjectApplymentRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Apply4Subject/CreateApplyForSubjectApplymentRequest.cs
@@ -17,6 +17,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string Name { get; set; } = string.Empty;
///
@@ -24,6 +25,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("mobile")]
[System.Text.Json.Serialization.JsonPropertyName("mobile")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string Mobile { get; set; } = string.Empty;
///
@@ -31,6 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdCardNumber { get; set; } = string.Empty;
}
@@ -255,6 +258,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("identification_name")]
[System.Text.Json.Serialization.JsonPropertyName("identification_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdentificationName { get; set; } = string.Empty;
///
@@ -262,6 +266,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("identification_number")]
[System.Text.Json.Serialization.JsonPropertyName("identification_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdentificationNumber { get; set; } = string.Empty;
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/BrandProfitSharing/CreateBrandProfitSharingOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/BrandProfitSharing/CreateBrandProfitSharingOrderRequest.cs
index 6f5acc14..243c8cde 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/BrandProfitSharing/CreateBrandProfitSharingOrderRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/BrandProfitSharing/CreateBrandProfitSharingOrderRequest.cs
@@ -31,6 +31,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? Name { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs
index 52a77e23..0612381c 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceApplyments/CreateEcommerceApplymentRequest.cs
@@ -99,6 +99,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_card_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdCardName { get; set; } = string.Empty;
///
@@ -106,6 +107,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_card_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdCardNumber { get; set; } = string.Empty;
///
@@ -130,6 +132,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_doc_name")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdDocumentName { get; set; } = string.Empty;
///
@@ -137,6 +140,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("id_doc_number")]
[System.Text.Json.Serialization.JsonPropertyName("id_doc_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string IdDocumentNumber { get; set; } = string.Empty;
///
@@ -161,6 +165,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("contact_name")]
[System.Text.Json.Serialization.JsonPropertyName("contact_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string ContactName { get; set; } = string.Empty;
///
@@ -168,6 +173,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("mobile_phone")]
[System.Text.Json.Serialization.JsonPropertyName("mobile_phone")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string ContactMobile { get; set; } = string.Empty;
///
@@ -175,6 +181,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("contact_id_card_number")]
[System.Text.Json.Serialization.JsonPropertyName("contact_id_card_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string ContactIdCardNumber { get; set; } = string.Empty;
///
@@ -182,6 +189,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("contact_email")]
[System.Text.Json.Serialization.JsonPropertyName("contact_email")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string ContactEmail { get; set; } = string.Empty;
}
@@ -199,6 +207,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("account_name")]
[System.Text.Json.Serialization.JsonPropertyName("account_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string AccountName { get; set; } = string.Empty;
///
@@ -206,6 +215,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("account_number")]
[System.Text.Json.Serialization.JsonPropertyName("account_number")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string AccountNumber { get; set; } = string.Empty;
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/CreateEcommerceProfitSharingOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/CreateEcommerceProfitSharingOrderRequest.cs
index b376c9fd..64efc8c4 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/CreateEcommerceProfitSharingOrderRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/CreateEcommerceProfitSharingOrderRequest.cs
@@ -31,6 +31,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("receiver_name")]
[System.Text.Json.Serialization.JsonPropertyName("receiver_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? Name { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/Receivers/AddEcommerceProfitSharingReceiverRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/Receivers/AddEcommerceProfitSharingReceiverRequest.cs
index d401d257..a0b6d11b 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/Receivers/AddEcommerceProfitSharingReceiverRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/EcommerceProfitSharing/Receivers/AddEcommerceProfitSharingReceiverRequest.cs
@@ -41,6 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("encrypted_name")]
[System.Text.Json.Serialization.JsonPropertyName("encrypted_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? EncryptedName { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/CreateProfitSharingOrderRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/CreateProfitSharingOrderRequest.cs
index 51b8a984..478c69d8 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/CreateProfitSharingOrderRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/CreateProfitSharingOrderRequest.cs
@@ -31,6 +31,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? Name { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverRequest.cs
index 473487ab..17ee9759 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverRequest.cs
@@ -41,10 +41,11 @@
public string Account { get; set; } = string.Empty;
///
- /// 获取或设置接收方名称。
+ /// 获取或设置接收方名称(需使用微信支付平台公钥加密)。
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? Name { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverResponse.cs
index ab70b54c..19c0b9fa 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverResponse.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/ProfitSharing/Receivers/AddProfitSharingReceiverResponse.cs
@@ -30,10 +30,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
public string Account { get; set; } = default!;
///
- /// 获取或设置接收方名称。
+ /// 获取或设置接收方名称(需使用商户私钥解密)。
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? Name { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/CreateSmartGuideRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/CreateSmartGuideRequest.cs
index 5ee60a05..25697942 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/CreateSmartGuideRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/CreateSmartGuideRequest.cs
@@ -41,6 +41,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string UserName { get; set; } = string.Empty;
///
@@ -48,6 +49,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("mobile")]
[System.Text.Json.Serialization.JsonPropertyName("mobile")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string UserMobile { get; set; } = string.Empty;
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/QuerySmartGuidesRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/QuerySmartGuidesRequest.cs
index 6679d14d..3ef24199 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/QuerySmartGuidesRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/QuerySmartGuidesRequest.cs
@@ -34,6 +34,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonIgnore]
[System.Text.Json.Serialization.JsonIgnore]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? UserMobile { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/UpdateSmartGuideRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/UpdateSmartGuideRequest.cs
index b6aba8f9..e8c0660b 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/UpdateSmartGuideRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/SmartGuide/UpdateSmartGuideRequest.cs
@@ -27,6 +27,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("name")]
[System.Text.Json.Serialization.JsonPropertyName("name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? UserName { get; set; }
///
@@ -34,6 +35,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("mobile")]
[System.Text.Json.Serialization.JsonPropertyName("mobile")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string? UserMobile { get; set; }
///
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchRequest.cs
index 52be9883..a74cd929 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchRequest.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Models/Transfer/Batches/CreateTransferBatchRequest.cs
@@ -45,6 +45,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("user_name")]
[System.Text.Json.Serialization.JsonPropertyName("user_name")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string UserName { get; set; } = string.Empty;
///
@@ -52,6 +53,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Models
///
[Newtonsoft.Json.JsonProperty("user_id_card")]
[System.Text.Json.Serialization.JsonPropertyName("user_id_card")]
+ [WechatTenpaySensitiveProperty(algorithm: Constants.EncryptionAlgorithms.RSA_2048_PKCS8_ECB)]
public string UserIdCardNumber { get; set; } = string.Empty;
}
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs
index 68399eba..0e04ff2b 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/WechatTenpayClient.cs
@@ -87,10 +87,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
flurlRequest.WithHeader("Wechatpay-Serial", request.WechatpayCertSerialNumber);
}
- if (AutoDecryptResponseSensitiveProperty)
+ if (AutoEncryptRequestSensitiveProperty)
{
- // this.EncryptRequestSensitiveProperty(request);
- throw new NotImplementedException();
+ this.EncryptRequestSensitiveProperty(request);
}
return flurlRequest;
diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/WechatTenpayRequestEncryptionTests.cs b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/WechatTenpayRequestEncryptionTests.cs
new file mode 100644
index 00000000..84601a16
--- /dev/null
+++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/WechatTenpayRequestEncryptionTests.cs
@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading;
+using System.Threading.Tasks;
+using Xunit;
+
+namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
+{
+ public class WechatTenpayRequestEncryptionTests
+ {
+ private const string RSA_CERTSN = "mock_sn";
+ private const string RSA_CERTIFICATE = "-----BEGIN CERTIFICATE-----MIID9jCCAt6gAwIBAgIUFGJAVFxIU/1hoxpZC8Tc2xKFJHowDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsTFFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3QgQ0EwHhcNMjAwODAxMDczNTE5WhcNMjUwNzMxMDczNTE5WjCBhzETMBEGA1UEAwwKMTYwMTEwMzMxNDEbMBkGA1UECgwS5b6u5L+h5ZWG5oi357O757ufMTMwMQYDVQQLDCroo5XkurrvvIjkuIrmtbfvvInmlZnogrLnp5HmioDmnInpmZDlhazlj7gxCzAJBgNVBAYMAkNOMREwDwYDVQQHDAhTaGVuWmhlbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKq4IUw5Rq6iTUahjkr+aYvmn3Hg2tHNDyIru7ZdthXw27BCwnwwDyufq6SBwXypuf3wXKpcFggZo5dwjDR6XxlGXzNDKdW7JQkTxQXqABZZVCq4yMMkVns3xbmDfAI57bW0O0F40+NOqmU9gjqRwGNvE9bE8N3y2VyxYcz53rU4FCrlCOfsFeF1Z3usbWOK5IOYXjmdzr96xVWasO0URJ60GwDZyGxRdkzd5kJy6HnVVqOUbn3t7mKbGkzQq/j+D+pyMlhjtRV475ks5uex4gVWZgEqT1b9sx1pUQvVPr6/ZXtqTJwSg/YvSCx5RBiYCskAyA/5XH9t1p/WV1zFhXUCAwEAAaOBgTB/MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgTwMGUGA1UdHwReMFwwWqBYoFaGVGh0dHA6Ly9ldmNhLml0cnVzLmNvbS5jbi9wdWJsaWMvaXRydXNjcmw/Q0E9MUJENDIyMEU1MERCQzA0QjA2QUQzOTc1NDk4NDZDMDFDM0U4RUJEMjANBgkqhkiG9w0BAQsFAAOCAQEAU44msdPGFg/r5JcWgUDEXWOqqCDiFNjWbhM/rO0A3TCV0yP5o7Se/yLsDizHGTUzZ2qg3bC02nn4RysEyMVQ+9tXsOtXQBHrmoZ5vS8ndqbE1YO33N6zxIUb0IN3yGZh3oVmQgTYYe1is4i5Sfiy7JdR6/uUrwQN13fzPaDCnNx6iVzrPSJJf1xiFdtpFFtK021prjMYG7csHiFQeelgyE8XtlQuLk0tsHBrJ2FHSdV4HISqONz0hMPL0xsZkBD/L/bvR3L0lqe8bsHOBCJOMyjxucI21mBRd7tc4AGiJlQt5jrUrbos5hul4/QUq7hFfZNDrEBMINbMyIpYWRbIqQ==-----END CERTIFICATE-----";
+ private const string RSA_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCquCFMOUauok1GoY5K/mmL5p9x4NrRzQ8iK7u2XbYV8NuwQsJ8MA8rn6ukgcF8qbn98FyqXBYIGaOXcIw0el8ZRl8zQynVuyUJE8UF6gAWWVQquMjDJFZ7N8W5g3wCOe21tDtBeNPjTqplPYI6kcBjbxPWxPDd8tlcsWHM+d61OBQq5Qjn7BXhdWd7rG1jiuSDmF45nc6/esVVmrDtFESetBsA2chsUXZM3eZCcuh51VajlG597e5imxpM0Kv4/g/qcjJYY7UVeO+ZLObnseIFVmYBKk9W/bMdaVEL1T6+v2V7akycEoP2L0gseUQYmArJAMgP+Vx/bdaf1ldcxYV1AgMBAAECggEBAIwkgTkYX5ymIXeU0cFgXfZ5iHQsWJUXl4++hOaswPf78+wasZrOvPVbqsRtvA8BKWx7byZuV6uomHGN85p0xjJyYV4siWAps7pi3z7+m7m89OnpLO18m/2kiAzFEfyl3yxlWqtha9dSUXCwcIJx+ZPmsEuC+hPI8oQ0HQvuJtNtcDmaFBp57kxjlO4Xm0xnvq2waSmAF4cO6Dk62gksu8G7//IyIHXqmRWSpI2b/Yqf84XtwLN8Zvq/3otYuWc3pFOaKHg2sJ/JwSU+yGdeIOtEXXFIDSD6p3KvIvjrD47Da4optYReXP1k6e721z+XPBFP31i58iu1K8KOyjjJfsECgYEA41D6V1TrON31OOsM4jAtqyY/LVNdzT+I/S6lQruO9siRRJDYlAOdbM9VZnW/3rduPMBu4undbMkL5i8olnwmLeWSupClA2WmUc8DWHlBO2s0lE+ZDZgOtpZ9qOBfm7L6jbjvzbGoyJgV6SeIavH5SMQbFku5rlIi12hAb0Kv4uUCgYEAwELkPOKDH06SFOiuOzJcI4VyjK0V5LcWjceTPkaT9d1evkrNgrHiG8CjYQ3V0lqSKhckFg2PwmPk72rC4n3aFCXurimv96rG5sBFFLgPbyoKZ3Z9JoDoe/6u6YIAV/GzxJ5QJaWQQ59MxToILYyq6aA6SrNOqRUPsKuvN8jBH1ECgYEA3dJ6yNgcRj0KfIWa5+qd1iMXiZKNuamjc3WeXTWL+DSW1bMHNcElUTYuHzMOjjavw2cBjjsrEWpLS09/qwHxe95IRfi6nksGd1Ss7hw9VM9z2rqmH4bf7LuEWlTB171bFQuAL1iL3VvUHdavH7WLTr/XsvUod/y89TlNj4UjACUCgYBBR3UPZyl2O8tF5isiVlsKhIj8UtiYK8IwqY7JGlWqqVs96VAWDCflnGbc0UHEhpQSToEmK7ygGCLnV6yMEoc1SBvebrEcupOGTcom2sgCypd1wbmElUhasYLaLhXHxn1vSQGVhr2Q+EmsvaOBM73kTU79hhwzNL97ERARNMy9wQKBgHCogsDPxSh8hEJR/PBom6v/3R+Ou86K8nzulbyHGkDM7I2R//zGx4en1VxWFhsqywsGedugv1BMkgEcCFkTjIXfYh9Uwn5iGUAZCczR5ZoETYAAzK2a/uaWf92iZEU0bHJaBA4egNxk1bFe+ECFTteN8Ag+UVtx0HU6ZNlyfetH-----END PRIVATE KEY-----";
+ private const string MockText = "mock_text";
+ private readonly Lazy MockClientInstance = new Lazy(() =>
+ {
+ var certManager = new Settings.InMemoryCertificateManager();
+ certManager.AddEntry(new Settings.CertificateEntry(
+ serialNumber: RSA_CERTSN,
+ certificate: RSA_CERTIFICATE,
+ effectiveTime: DateTimeOffset.MinValue,
+ expireTime: DateTimeOffset.MaxValue
+ ));
+ return new WechatTenpayClient(new WechatTenpayClientOptions()
+ {
+ CertificateManager = certManager
+ });
+ }, isThreadSafe: false);
+
+ [Fact(DisplayName = "加密请求中的敏感数据([POST] /profitsharing/receivers/add)")]
+ public void DecryptResponseSensitiveProperty_AddProfitSharingReceiverRequest()
+ {
+ var mock = new Models.AddProfitSharingReceiverRequest()
+ {
+ Account = MockText,
+ Name = MockText
+ };
+ var data = MockClientInstance.Value.EncryptRequestSensitiveProperty(mock);
+
+ Assert.Equal(MockText, data.Account);
+ Assert.Equal(MockText, Utilities.RSAUtility.DecryptWithECB(RSA_PRIVATE_KEY, data.Name));
+ }
+ }
+}