refactor(tenpayv3): 优化加解密及哈希算法工具类

This commit is contained in:
Fu Diwei 2024-02-05 10:53:59 +08:00 committed by RHQYZ
parent 70315cd128
commit 70611189cc
25 changed files with 788 additions and 671 deletions

View File

@ -1,8 +1,9 @@
using System;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
public static class WechatTenpayClientEventDecryptionExtensions
{
/// <summary>
@ -14,7 +15,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
public static WechatTenpayEvent DeserializeEvent(this WechatTenpayClient client, string webhookJson)
{
if (client is null) throw new ArgumentNullException(nameof(client));
if (string.IsNullOrEmpty(webhookJson)) throw new ArgumentNullException(webhookJson);
if (webhookJson is null) throw new ArgumentNullException(webhookJson);
return client.JsonSerializer.Deserialize<WechatTenpayEvent>(webhookJson);
}
@ -56,11 +57,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
try
{
plainJson = Utilities.AESUtility.DecryptWithGCM(
key: client.Credentials.MerchantV3Secret,
nonce: webhookEventResource.Nonce,
aad: webhookEventResource.AssociatedData,
cipherText: webhookEventResource.CipherText
);
encodingKey: new EncodedString(client.Credentials.MerchantV3Secret, EncodingKinds.Literal),
encodingNonce: new EncodedString(webhookEventResource.Nonce, EncodingKinds.Literal),
encodingAssociatedData: new EncodedString(webhookEventResource.AssociatedData, EncodingKinds.Literal),
encodingCipher: new EncodedString(webhookEventResource.CipherText, EncodingKinds.Base64)
)!;
}
catch (Exception ex)
{
@ -75,17 +76,17 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
// REF: https://pay.weixin.qq.com/docs/merchant/development/shangmi/guide.html
// 由于 SM4 密钥长度的限制,密钥由 APIv3 密钥通过国密 SM3 Hash 计算生成。SM4 密钥取其摘要256bit的前 128bit。
byte[] secretBytes = Utilities.SM3Utility.Hash(Encoding.UTF8.GetBytes(client.Credentials.MerchantV3Secret));
byte[] secretBytes = Utilities.SM3Utility.Hash(EncodedString.FromLiteralString(client.Credentials.MerchantV3Secret));
byte[] keyBytes = new byte[16];
Array.Copy(secretBytes, keyBytes, keyBytes.Length);
byte[] plainBytes = Utilities.SM4Utility.DecryptWithGCM(
keyBytes: keyBytes,
nonceBytes: Encoding.UTF8.GetBytes(webhookEventResource.Nonce),
aadBytes: webhookEventResource.AssociatedData is null ? null : Encoding.UTF8.GetBytes(webhookEventResource.AssociatedData),
cipherBytes: Convert.FromBase64String(webhookEventResource.CipherText)
nonceBytes: EncodedString.FromLiteralString(webhookEventResource.Nonce),
associatedDataBytes: EncodedString.FromLiteralString(webhookEventResource.AssociatedData),
cipherBytes: EncodedString.FromBase64String(webhookEventResource.CipherText)
);
plainJson = Encoding.UTF8.GetString(plainBytes);
plainJson = EncodedString.ToLiteralString(plainBytes).Value!;
}
catch (Exception ex)
{

View File

@ -6,6 +6,8 @@ using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
public static class WechatTenpayClientExecuteEcommerceExtensions
{
#region Account
@ -64,7 +66,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (request.FileHash is null)
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower();
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
if (request.FileContentType is null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";

View File

@ -6,6 +6,8 @@ using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
public static class WechatTenpayClientExecuteMarketingBankExtensions
{
/// <summary>
@ -26,7 +28,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".txt";
if (request.FileHash is null)
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes ?? Array.Empty<byte>())).Replace("-", string.Empty).ToLower();
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes ?? Array.Empty<byte>())).Value!.ToLower();
if (request.FileContentType is null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "text/plain";

View File

@ -6,6 +6,8 @@ using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
public static class WechatTenpayClientExecuteMarketingMediaExtensions
{
/// <summary>
@ -30,7 +32,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (request.FileHash is null)
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower();
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
if (request.FileContentType is null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";

View File

@ -6,6 +6,8 @@ using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
public static class WechatTenpayClientExecuteMarketingShoppingReceiptExtensions
{
/// <summary>
@ -25,7 +27,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (request.FileHash is null)
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower();
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
if (request.FileContentType is null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";

View File

@ -6,6 +6,8 @@ using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
public static class WechatTenpayClientExecuteMerchantMediaExtensions
{
/// <summary>
@ -27,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (request.FileHash is null)
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower();
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
if (request.FileContentType is null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";
@ -56,7 +58,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".mp4";
if (request.FileHash is null)
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower();
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
if (request.FileContentType is null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4";

View File

@ -7,6 +7,8 @@ using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
public static class WechatTenpayClientExecuteMerchantServiceExtensions
{
/// <summary>
@ -250,7 +252,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (request.FileHash is null)
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower();
request.FileHash = EncodedString.ToHexString(Utilities.SHA256Utility.Hash(request.FileBytes)).Value!.ToLower();
if (request.FileContentType is null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png";

View File

@ -33,10 +33,10 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
string nonce = Guid.NewGuid().ToString("N");
string package = $"prepay_id={prepayId}";
string sign = Utilities.RSAUtility.SignWithSHA256(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
string sign = Utilities.RSAUtility.Sign(
privateKeyPem: client.Credentials.MerchantCertificatePrivateKey,
message: $"{appId}\n{timestamp}\n{nonce}\n{package}\n"
);
)!;
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
{
@ -85,10 +85,10 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
string nonce = Guid.NewGuid().ToString("N");
string sign = Utilities.RSAUtility.SignWithSHA256(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
string sign = Utilities.RSAUtility.Sign(
privateKeyPem: client.Credentials.MerchantCertificatePrivateKey,
message: $"{appId}\n{timestamp}\n{nonce}\n{prepayId}\n"
);
)!;
return new ReadOnlyDictionary<string, string>(new Dictionary<string, string>()
{

View File

@ -82,29 +82,30 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1:
{
newValue = RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: oldValue
);
certificatePem: certificate,
plainData: oldValue,
paddingMode: RSAUtility.PADDING_MODE_OAEPWITHSHA1ANDMGF1
)!;
}
break;
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1:
{
newValue = RSAUtility.EncryptWithECBByCertificate(
certificate: certificate,
plainText: oldValue,
paddingMode: "PKCS1PADDING"
);
certificatePem: certificate,
plainData: oldValue,
paddingMode: RSAUtility.PADDING_MODE_PKCS1
)!;
}
break;
case Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1:
{
newValue = SM2Utility.EncryptByCertificate(
certificate: certificate,
plainText: oldValue,
certificatePem: certificate,
plainData: oldValue,
asn1Encoding: true
);
)!;
}
break;

View File

@ -1,10 +1,10 @@
using System;
using System.Linq;
using System.Reflection;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities;
@ -37,11 +37,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
throw new WechatTenpayException("Failed to decrypt response, because the merchant private key is not set.");
certificate.EncryptCertificate.CipherText = AESUtility.DecryptWithGCM(
key: client.Credentials.MerchantV3Secret,
nonce: certificate.EncryptCertificate.Nonce,
aad: certificate.EncryptCertificate.AssociatedData,
cipherText: certificate.EncryptCertificate.CipherText
);
encodingKey: new EncodedString(client.Credentials.MerchantV3Secret, EncodingKinds.Literal),
encodingNonce: new EncodedString(certificate.EncryptCertificate.Nonce, EncodingKinds.Literal),
encodingAssociatedData: new EncodedString(certificate.EncryptCertificate.AssociatedData, EncodingKinds.Literal),
encodingCipher: new EncodedString(certificate.EncryptCertificate.CipherText, EncodingKinds.Base64)
)!;
}
break;
@ -52,17 +52,17 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
// REF: https://pay.weixin.qq.com/docs/merchant/development/shangmi/guide.html
// 由于 SM4 密钥长度的限制,密钥由 APIv3 密钥通过国密 SM3 Hash 计算生成。SM4 密钥取其摘要256bit的前 128bit。
byte[] secretBytes = SM3Utility.Hash(Encoding.UTF8.GetBytes(client.Credentials.MerchantV3Secret));
byte[] secretBytes = SM3Utility.Hash(EncodedString.FromLiteralString(client.Credentials.MerchantV3Secret));
byte[] keyBytes = new byte[16];
Array.Copy(secretBytes, keyBytes, keyBytes.Length);
byte[] plainBytes = SM4Utility.DecryptWithGCM(
keyBytes: keyBytes,
nonceBytes: Encoding.UTF8.GetBytes(certificate.EncryptCertificate.Nonce),
aadBytes: Encoding.UTF8.GetBytes(certificate.EncryptCertificate.AssociatedData ?? string.Empty),
cipherBytes: Convert.FromBase64String(certificate.EncryptCertificate.CipherText)
nonceBytes: EncodedString.FromLiteralString(certificate.EncryptCertificate.Nonce),
associatedDataBytes: EncodedString.FromLiteralString(certificate.EncryptCertificate.AssociatedData),
cipherBytes: EncodedString.FromBase64String(certificate.EncryptCertificate.CipherText)
);
certificate.EncryptCertificate.CipherText = Encoding.UTF8.GetString(plainBytes);
certificate.EncryptCertificate.CipherText = EncodedString.ToLiteralString(plainBytes).Value!;
}
break;
@ -123,29 +123,30 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS8_OAEP_WITH_SHA1_AND_MGF1:
{
newValue = RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue
);
privateKeyPem: client.Credentials.MerchantCertificatePrivateKey,
encodingCipher: new EncodedString(oldValue, EncodingKinds.Base64),
paddingMode: RSAUtility.PADDING_MODE_OAEPWITHSHA1ANDMGF1
)!;
}
break;
case Constants.EncryptionAlgorithms.RSA_2048_ECB_PKCS1:
{
newValue = RSAUtility.DecryptWithECB(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue,
paddingMode: "PKCS1PADDING"
);
privateKeyPem: client.Credentials.MerchantCertificatePrivateKey,
encodingCipher: new EncodedString(oldValue, EncodingKinds.Base64),
paddingMode: RSAUtility.PADDING_MODE_PKCS1
)!;
}
break;
case Constants.EncryptionAlgorithms.SM2_C1C3C2_ASN1:
{
newValue = SM2Utility.Decrypt(
privateKey: client.Credentials.MerchantCertificatePrivateKey,
cipherText: oldValue,
privateKeyPem: client.Credentials.MerchantCertificatePrivateKey,
encodingCipher: new EncodedString(oldValue, EncodingKinds.Base64),
asn1Encoding: true
);
)!;
}
break;

View File

@ -2,6 +2,7 @@ using System;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
using SKIT.FlurlHttpClient.Primitives;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
internal static class WechatTenpayClientSigningExtensions
@ -36,10 +37,10 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
error = null;
try
{
return Utilities.RSAUtility.VerifyWithSHA256ByCertificate(
certificate: entry.Value.Certificate,
return Utilities.RSAUtility.VerifyByCertificate(
certificatePem: entry.Value.Certificate,
message: GenerateMessageForSignature(timestamp: strTimestamp, nonce: strNonce, body: strContent),
signature: strSignature
encodingSignature: new EncodedString(strSignature, EncodingKinds.Base64)
);
}
catch (Exception ex)
@ -74,9 +75,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
try
{
return Utilities.SM2Utility.VerifyWithSM3ByCertificate(
certificate: entry.Value.Certificate,
certificatePem: entry.Value.Certificate,
message: GenerateMessageForSignature(timestamp: strTimestamp, nonce: strNonce, body: strContent),
signature: strSignature
encodingSignature: new EncodedString(strSignature, EncodingKinds.Base64)
);
}
catch (Exception ex)

View File

@ -56,7 +56,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
{
try
{
signText = Utilities.RSAUtility.SignWithSHA256(_mchCertPk, msgText);
signText = Utilities.RSAUtility.Sign(_mchCertPk, msgText).Value!;
}
catch (Exception ex)
{
@ -69,7 +69,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
{
try
{
signText = Utilities.SM2Utility.SignWithSM3(_mchCertPk, msgText);
signText = Utilities.SM2Utility.SignWithSM3(_mchCertPk, msgText).Value!;
}
catch (Exception ex)
{

View File

@ -75,16 +75,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings
case ALGORITHM_TYPE_RSA:
{
SerialNumber = Utilities.RSAUtility.ExportSerialNumberFromCertificate(certificate).ToUpper();
EffectiveTime = Utilities.RSAUtility.ExportEffectiveTimeFromCertificate(certificate);
ExpireTime = Utilities.RSAUtility.ExportExpireTimeFromCertificate(certificate);
EffectiveTime = Utilities.RSAUtility.ExportValidFromDateFromCertificate(certificate);
ExpireTime = Utilities.RSAUtility.ExportValidToDateFromCertificate(certificate);
}
break;
case ALGORITHM_TYPE_SM2:
{
SerialNumber = Utilities.SM2Utility.ExportSerialNumberFromCertificate(certificate).ToUpper();
EffectiveTime = Utilities.SM2Utility.ExportEffectiveTimeFromCertificate(certificate);
ExpireTime = Utilities.SM2Utility.ExportExpireTimeFromCertificate(certificate);
EffectiveTime = Utilities.SM2Utility.ExportValidFromDateFromCertificate(certificate);
ExpireTime = Utilities.SM2Utility.ExportValidToDateFromCertificate(certificate);
}
break;

View File

@ -1,29 +1,32 @@
using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
using SKIT.FlurlHttpClient.Primitives;
/// <summary>
/// AES 算法工具类。
/// </summary>
public static class AESUtility
{
private const string AES_CIPHER_ALGORITHM_GCM = "AES/GCM";
private const string AES_CIPHER_PADDING_NOPADDING = "NoPadding";
/// <summary>
/// 填充模式NoPadding。
/// </summary>
public const string PADDING_MODE_NOPADDING = "NoPadding";
/// <summary>
/// 基于 GCM 模式解密数据。
/// </summary>
/// <param name="keyBytes">AES 密钥字节数组。</param>
/// <param name="nonceBytes">加密使用的初始化向量字节数组。</param>
/// <param name="aadBytes">加密使用的附加数据字节数组。</param>
/// <param name="nonceBytes">初始化向量字节数组。</param>
/// <param name="associatedDataBytes">附加数据字节数组。</param>
/// <param name="cipherBytes">待解密数据字节数组。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="AES_CIPHER_PADDING_NOPADDING"/></param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_NOPADDING"/></param>
/// <returns>解密后的数据字节数组。</returns>
public static byte[] DecryptWithGCM(byte[] keyBytes, byte[] nonceBytes, byte[]? aadBytes, byte[] cipherBytes, string paddingMode = AES_CIPHER_PADDING_NOPADDING)
public static byte[] DecryptWithGCM(byte[] keyBytes, byte[] nonceBytes, byte[]? associatedDataBytes, byte[] cipherBytes, string paddingMode = PADDING_MODE_NOPADDING)
{
const int KEY_LENGTH_BYTE = 32;
const int NONCE_LENGTH_BYTE = 12;
@ -36,12 +39,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (cipherBytes is null) throw new ArgumentNullException(nameof(cipherBytes));
if (cipherBytes.Length < TAG_LENGTH_BYTE) throw new ArgumentException($"Invalid cipher byte length (expected: more than {TAG_LENGTH_BYTE}, actual: {cipherBytes.Length}).", nameof(cipherBytes));
IBufferedCipher cipher = CipherUtilities.GetCipher(string.Format("{0}/{1}", AES_CIPHER_ALGORITHM_GCM, paddingMode));
IBufferedCipher cipher = CipherUtilities.GetCipher($"AES/GCM/{paddingMode}");
ICipherParameters cipherParams = new AeadParameters(
new KeyParameter(keyBytes),
TAG_LENGTH_BYTE * 8,
nonceBytes,
aadBytes
associatedDataBytes
);
cipher.Init(false, cipherParams);
byte[] plainBytes = new byte[cipher.GetOutputSize(cipherBytes.Length)];
@ -53,26 +56,26 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 基于 GCM 模式解密数据。
/// </summary>
/// <param name="key">AES 密钥。</param>
/// <param name="nonce">加密使用的初始化向量。</param>
/// <param name="aad">加密使用的附加数据包。</param>
/// <param name="cipherText">经 Base64 编码后的待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="AES_CIPHER_PADDING_NOPADDING"/></param>
/// <returns>解密后的文本数据。</returns>
public static string DecryptWithGCM(string key, string nonce, string? aad, string cipherText, string paddingMode = AES_CIPHER_PADDING_NOPADDING)
/// <param name="encodingKey">经过编码后的(通常为 Base64AES 密钥。</param>
/// <param name="encodingNonce">经过编码后的(通常为 Base64初始化向量。</param>
/// <param name="encodingAssociatedData">经过编码后的(通常为 Base64附加数据。</param>
/// <param name="encodingCipher">经过编码后的(通常为 Base64待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_NOPADDING"/></param>
/// <returns>解密后的数据。</returns>
public static EncodedString DecryptWithGCM(EncodedString encodingKey, EncodedString encodingNonce, EncodedString encodingAssociatedData, EncodedString encodingCipher, string paddingMode = PADDING_MODE_NOPADDING)
{
if (key is null) throw new ArgumentNullException(nameof(key));
if (nonce is null) throw new ArgumentNullException(nameof(nonce));
if (cipherText is null) throw new ArgumentNullException(nameof(cipherText));
if (encodingKey.Value is null) throw new ArgumentNullException(nameof(encodingKey));
if (encodingNonce.Value is null) throw new ArgumentNullException(nameof(encodingNonce));
if (encodingCipher.Value is null) throw new ArgumentNullException(nameof(encodingCipher));
byte[] plainBytes = DecryptWithGCM(
keyBytes: Encoding.UTF8.GetBytes(key),
nonceBytes: Encoding.UTF8.GetBytes(nonce),
aadBytes: aad is not null ? Encoding.UTF8.GetBytes(aad) : null,
cipherBytes: Convert.FromBase64String(cipherText),
keyBytes: EncodedString.FromString(encodingKey, fallbackEncodingKind: EncodingKinds.Base64),
nonceBytes: EncodedString.FromString(encodingNonce, fallbackEncodingKind: EncodingKinds.Base64),
associatedDataBytes: encodingAssociatedData.Value is not null ? EncodedString.FromString(encodingAssociatedData, fallbackEncodingKind: EncodingKinds.Base64) : null,
cipherBytes: EncodedString.FromString(encodingCipher, fallbackEncodingKind: EncodingKinds.Base64),
paddingMode: paddingMode
);
return Encoding.UTF8.GetString(plainBytes);
return EncodedString.ToLiteralString(plainBytes);
}
}
}

View File

@ -1,72 +1,143 @@
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;
using Org.BouncyCastle.X509;
using Org.BouncyCastle.Asn1.Pkcs;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
using SKIT.FlurlHttpClient.Primitives;
/// <summary>
/// RSA 算法工具类。
/// </summary>
public static class RSAUtility
{
private const string RSA_CIPHER_ALGORITHM_ECB = "RSA/ECB";
private const string RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1 = "OAEPWITHSHA1ANDMGF1PADDING";
private const string RSA_SIGNER_ALGORITHM_SHA256 = "SHA-256withRSA";
/// <summary>
/// 填充模式OAEPwithSHA-256andMGF1Padding。
/// </summary>
public const string PADDING_MODE_OAEPWITHSHA1ANDMGF1 = "OAEPWITHSHA1ANDMGF1PADDING";
private static byte[] ConvertPrivateKeyPkcs8PemToByteArray(string privateKey)
/// <summary>
/// 填充模式PKCS1Padding。
/// </summary>
public const string PADDING_MODE_PKCS1 = "PKCS1PADDING";
/// <summary>
/// 签名算法SHA-256withRSA。
/// </summary>
public const string DIGEST_ALGORITHM_SHA256 = "SHA-256withRSA";
private static byte[] ConvertPrivateKeyPemToByteArray(string privateKeyPem)
{
privateKey = privateKey
if (!privateKeyPem.StartsWith("-----BEGIN PRIVATE KEY-----"))
{
using (TextReader textReader = new StringReader(privateKeyPem))
using (PemReader pemReader = new PemReader(textReader))
{
object pemObject = pemReader.ReadObject();
if (pemObject is AsymmetricCipherKeyPair)
{
// PKCS#1 格式
AsymmetricCipherKeyPair cipherKeyPair = (AsymmetricCipherKeyPair)pemObject;
using (TextWriter textWriter = new StringWriter())
using (PemWriter pemWriter = new PemWriter(textWriter))
{
Pkcs8Generator pkcs8 = new Pkcs8Generator(cipherKeyPair.Private);
pemWriter.WriteObject(pkcs8);
pemWriter.Writer.Close();
privateKeyPem = textWriter.ToString()!;
}
}
else if (pemObject is RsaPrivateCrtKeyParameters)
{
// PKCS#8 格式
}
else
{
throw new NotSupportedException("Private key format is not supported.");
}
}
}
privateKeyPem = privateKeyPem
.Replace("-----BEGIN PRIVATE KEY-----", string.Empty)
.Replace("-----END PRIVATE KEY-----", string.Empty);
privateKey = Regex.Replace(privateKey, "\\s+", string.Empty);
return Convert.FromBase64String(privateKey);
privateKeyPem = Regex.Replace(privateKeyPem, "\\s+", string.Empty);
return Convert.FromBase64String(privateKeyPem);
}
private static byte[] ConvertPublicKeyPkcs8PemToByteArray(string publicKey)
private static byte[] ConvertPublicKeyPemToByteArray(string publicKeyPem)
{
publicKey = publicKey
if (!publicKeyPem.StartsWith("-----BEGIN PUBLIC KEY-----"))
{
using (TextReader textReader = new StringReader(publicKeyPem))
using (PemReader pemReader = new PemReader(textReader))
{
object pemObject = pemReader.ReadObject();
if (pemObject is RsaKeyParameters)
{
// PKCS#1 或 PKCS#8 格式
RsaKeyParameters rsaKeyParams = (RsaKeyParameters)pemObject;
using (TextWriter textWriter = new StringWriter())
using (PemWriter pemWriter = new PemWriter(textWriter))
{
pemWriter.WriteObject(rsaKeyParams);
pemWriter.Writer.Close();
publicKeyPem = textWriter.ToString()!;
}
}
else
{
throw new NotSupportedException("Public key format is not supported.");
}
}
}
publicKeyPem = publicKeyPem
.Replace("-----BEGIN PUBLIC KEY-----", string.Empty)
.Replace("-----END PUBLIC KEY-----", string.Empty);
publicKey = Regex.Replace(publicKey, "\\s+", string.Empty);
return Convert.FromBase64String(publicKey);
publicKeyPem = Regex.Replace(publicKeyPem, "\\s+", string.Empty);
return Convert.FromBase64String(publicKeyPem);
}
private static X509Certificate ParseCertificatePemToX509(string certificate)
private static X509Certificate ParseCertificatePemToX509(string certificatePem)
{
using (TextReader sreader = new StringReader(certificate))
using (TextReader sreader = new StringReader(certificatePem))
{
PemReader pemReader = new PemReader(sreader);
return (X509Certificate)pemReader.ReadObject();
}
}
private static RsaKeyParameters ParsePrivateKeyPemToPrivateKeyParameters(byte[] privateKeyBytes)
private static RsaKeyParameters ParsePrivateKeyToParameters(byte[] privateKeyBytes)
{
return (RsaKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);
}
private static RsaKeyParameters ParsePublicKeyPemToPublicKeyParameters(byte[] publicKeyBytes)
private static RsaKeyParameters ParsePublicKeyToParameters(byte[] publicKeyBytes)
{
return (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKeyBytes);
}
private static byte[] SignWithSHA256(RsaKeyParameters rsaPrivateKeyParams, byte[] msgBytes)
private static byte[] Sign(RsaKeyParameters rsaPrivateKeyParams, byte[] msgBytes, string digestAlgorithm)
{
ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256);
ISigner signer = SignerUtilities.GetSigner(digestAlgorithm);
signer.Init(true, rsaPrivateKeyParams);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.GenerateSignature();
}
private static bool VerifyWithSHA256(RsaKeyParameters rsaPublicKeyParams, byte[] msgBytes, byte[] signBytes)
private static bool Verify(RsaKeyParameters rsaPublicKeyParams, byte[] msgBytes, byte[] signBytes, string digestAlgorithm)
{
ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256);
ISigner signer = SignerUtilities.GetSigner(digestAlgorithm);
signer.Init(false, rsaPublicKeyParams);
signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
return signer.VerifySignature(signBytes);
@ -74,182 +145,187 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
private static byte[] DecryptWithECB(RsaKeyParameters rsaPrivateKeyParams, byte[] cipherBytes, string paddingMode)
{
IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingMode}");
IBufferedCipher cipher = CipherUtilities.GetCipher($"RSA/ECB/{paddingMode}");
cipher.Init(false, rsaPrivateKeyParams);
return cipher.DoFinal(cipherBytes);
}
private static byte[] EncryptWithECB(RsaKeyParameters rsaPublicKeyParams, byte[] plainBytes, string paddingMode)
{
IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingMode}");
IBufferedCipher cipher = CipherUtilities.GetCipher($"RSA/ECB/{paddingMode}");
cipher.Init(true, rsaPublicKeyParams);
return cipher.DoFinal(plainBytes);
}
/// <summary>
/// 使用私钥基于 SHA-256 算法生成签名。
/// 使用私钥生成签名。
/// </summary>
/// <param name="privateKeyBytes">PKCS#8 私钥字节数组。</param>
/// <param name="privateKeyBytes">PKCS#1/PKCS#8 私钥字节数组。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/></param>
/// <returns>签名字节数组。</returns>
public static byte[] SignWithSHA256(byte[] privateKeyBytes, byte[] msgBytes)
public static byte[] Sign(byte[] privateKeyBytes, byte[] msgBytes, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
{
if (privateKeyBytes is null) throw new ArgumentNullException(nameof(privateKeyBytes));
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyPemToPrivateKeyParameters(privateKeyBytes);
return SignWithSHA256(rsaPrivateKeyParams, msgBytes);
RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyToParameters(privateKeyBytes);
return Sign(rsaPrivateKeyParams, msgBytes, digestAlgorithm);
}
/// <summary>
/// 使用私钥基于 SHA-256 算法生成签名。
/// 使用私钥生成签名。
/// </summary>
/// <param name="privateKey">PKCS#8 私钥PEM 格式)。</param>
/// <param name="message">待签名的文本数据。</param>
/// <returns>经 Base64 编码的签名。</returns>
public static string SignWithSHA256(string privateKey, string message)
/// <param name="privateKeyPem">PKCS#1/PKCS#8 私钥PEM 格式)。</param>
/// <param name="message">待签名的数据。</param>
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/></param>
/// <returns>经过 Base64 编码的签名。</returns>
public static EncodedString Sign(string privateKeyPem, string message, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
{
if (privateKey is null) throw new ArgumentNullException(nameof(privateKey));
if (privateKeyPem is null) throw new ArgumentNullException(nameof(privateKeyPem));
if (message is null) throw new ArgumentNullException(nameof(message));
byte[] privateKeyBytes = ConvertPrivateKeyPkcs8PemToByteArray(privateKey);
byte[] msgBytes = Encoding.UTF8.GetBytes(message);
byte[] signBytes = SignWithSHA256(privateKeyBytes, msgBytes);
return Convert.ToBase64String(signBytes);
byte[] privateKeyBytes = ConvertPrivateKeyPemToByteArray(privateKeyPem);
byte[] msgBytes = EncodedString.FromLiteralString(message);
byte[] signBytes = Sign(privateKeyBytes, msgBytes, digestAlgorithm);
return EncodedString.ToBase64String(signBytes);
}
/// <summary>
/// 使用公钥基于 SHA-256 算法验证签名。
/// 使用公钥验证签名。
/// </summary>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数据。</param>
/// <param name="msgBytes">待验证的数据字节数据。</param>
/// <param name="signBytes">待验证的签名字节数据。</param>
/// <param name="publicKeyBytes">PKCS#1/PKCS#8 公钥字节数组。</param>
/// <param name="msgBytes">待验证的数据字节数组。</param>
/// <param name="signBytes">签名字节数组。</param>
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/></param>
/// <returns>验证结果。</returns>
public static bool VerifyWithSHA256(byte[] publicKeyBytes, byte[] msgBytes, byte[] signBytes)
public static bool Verify(byte[] publicKeyBytes, byte[] msgBytes, byte[] signBytes, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
{
if (publicKeyBytes is null) throw new ArgumentNullException(nameof(publicKeyBytes));
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
if (signBytes is null) throw new ArgumentNullException(nameof(signBytes));
RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyPemToPublicKeyParameters(publicKeyBytes);
return VerifyWithSHA256(rsaPublicKeyParams, msgBytes, signBytes);
RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyToParameters(publicKeyBytes);
return Verify(rsaPublicKeyParams, msgBytes, signBytes, digestAlgorithm);
}
/// <summary>
/// 使用公钥基于 SHA-256 算法验证签名。
/// 使用公钥验证签名。
/// </summary>
/// <param name="publicKey">PKCS#8 公钥PEM 格式)。</param>
/// <param name="message">待验证的文本数据。</param>
/// <param name="signature">经 Base64 编码的待验证的签名。</param>
/// <param name="publicKeyPem">PKCS#1/PKCS#8 公钥PEM 格式)。</param>
/// <param name="message">待验证的数据。</param>
/// <param name="encodingSignature">经过编码后的(通常为 Base64签名。</param>
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/></param>
/// <returns>验证结果。</returns>
public static bool VerifyWithSHA256(string publicKey, string message, string signature)
public static bool Verify(string publicKeyPem, string message, EncodedString encodingSignature, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
{
if (publicKey is null) throw new ArgumentNullException(nameof(publicKey));
if (publicKeyPem is null) throw new ArgumentNullException(nameof(publicKeyPem));
if (message is null) throw new ArgumentNullException(nameof(message));
if (signature is null) throw new ArgumentNullException(nameof(signature));
if (encodingSignature.Value is null) throw new ArgumentNullException(nameof(encodingSignature));
byte[] publicKeyBytes = ConvertPublicKeyPkcs8PemToByteArray(publicKey);
byte[] msgBytes = Encoding.UTF8.GetBytes(message);
byte[] signBytes = Convert.FromBase64String(signature);
return VerifyWithSHA256(publicKeyBytes, msgBytes, signBytes);
byte[] publicKeyBytes = ConvertPublicKeyPemToByteArray(publicKeyPem);
byte[] msgBytes = EncodedString.FromLiteralString(message);
byte[] signBytes = EncodedString.FromString(encodingSignature, fallbackEncodingKind: EncodingKinds.Base64);
return Verify(publicKeyBytes, msgBytes, signBytes, digestAlgorithm);
}
/// <summary>
/// 使用证书基于 SHA-256 算法验证签名。
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="message">待验证的文本数据。</param>
/// <param name="signature">经 Base64 编码的待验证的签名。</param>
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <param name="message">待验证的数据。</param>
/// <param name="encodingSignature">经过编码后的(通常为 Base64签名。</param>
/// <param name="digestAlgorithm">签名算法。(默认值:<see cref="DIGEST_ALGORITHM_SHA256"/></param>
/// <returns>验证结果。</returns>
public static bool VerifyWithSHA256ByCertificate(string certificate, string message, string signature)
public static bool VerifyByCertificate(string certificatePem, string message, EncodedString encodingSignature, string digestAlgorithm = DIGEST_ALGORITHM_SHA256)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
string publicKey = ExportPublicKeyFromCertificate(certificate);
return VerifyWithSHA256(publicKey, message, signature);
string publicKeyPem = ExportPublicKeyFromCertificate(certificatePem);
return Verify(publicKeyPem, message, encodingSignature, digestAlgorithm);
}
/// <summary>
/// 使用私钥基于 ECB 模式解密数据。
/// </summary>
/// <param name="privateKeyBytes">PKCS#8 私钥字节数据。</param>
/// <param name="cipherBytes">待解密的数据字节数。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/></param>
/// <param name="privateKeyBytes">PKCS#1/PKCS#8 私钥字节数组。</param>
/// <param name="cipherBytes">待解密的数据字节数。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/></param>
/// <returns>解密后的数据字节数组。</returns>
public static byte[] DecryptWithECB(byte[] privateKeyBytes, byte[] cipherBytes, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1)
public static byte[] DecryptWithECB(byte[] privateKeyBytes, byte[] cipherBytes, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
{
if (privateKeyBytes is null) throw new ArgumentNullException(nameof(privateKeyBytes));
if (cipherBytes is null) throw new ArgumentNullException(nameof(cipherBytes));
RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyPemToPrivateKeyParameters(privateKeyBytes);
RsaKeyParameters rsaPrivateKeyParams = ParsePrivateKeyToParameters(privateKeyBytes);
return DecryptWithECB(rsaPrivateKeyParams, cipherBytes, paddingMode);
}
/// <summary>
/// 使用私钥基于 ECB 模式解密数据。
/// </summary>
/// <param name="privateKey">PKCS#8 私钥PEM 格式)。</param>
/// <param name="cipherText">经 Base64 编码的待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/></param>
/// <returns>解密后的文本数据。</returns>
public static string DecryptWithECB(string privateKey, string cipherText, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1)
/// <param name="privateKeyPem">PKCS#1/PKCS#8 私钥PEM 格式)。</param>
/// <param name="encodingCipher">经过编码后的(通常为 Base64待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/></param>
/// <returns>解密后的数据。</returns>
public static EncodedString DecryptWithECB(string privateKeyPem, EncodedString encodingCipher, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
{
if (privateKey is null) throw new ArgumentNullException(nameof(privateKey));
if (cipherText is null) throw new ArgumentNullException(nameof(cipherText));
if (privateKeyPem is null) throw new ArgumentNullException(nameof(privateKeyPem));
if (encodingCipher.Value is null) throw new ArgumentNullException(nameof(encodingCipher));
byte[] privateKeyBytes = ConvertPrivateKeyPkcs8PemToByteArray(privateKey);
byte[] cipherBytes = Convert.FromBase64String(cipherText);
byte[] privateKeyBytes = ConvertPrivateKeyPemToByteArray(privateKeyPem);
byte[] cipherBytes = EncodedString.FromString(encodingCipher, fallbackEncodingKind: EncodingKinds.Base64);
byte[] plainBytes = DecryptWithECB(privateKeyBytes, cipherBytes, paddingMode);
return Encoding.UTF8.GetString(plainBytes);
return EncodedString.ToLiteralString(plainBytes);
}
/// <summary>
/// 使用公钥基于 ECB 模式加密数据。
/// </summary>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数据。</param>
/// <param name="plainBytes">待加密的数据字节数。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/></param>
/// <param name="publicKeyBytes">PKCS#1/PKCS#8 公钥字节数组。</param>
/// <param name="plainBytes">待加密的数据字节数。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/></param>
/// <returns>加密后的数据字节数组。</returns>
public static byte[] EncryptWithECB(byte[] publicKeyBytes, byte[] plainBytes, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1)
public static byte[] EncryptWithECB(byte[] publicKeyBytes, byte[] plainBytes, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
{
if (publicKeyBytes is null) throw new ArgumentNullException(nameof(publicKeyBytes));
if (plainBytes is null) throw new ArgumentNullException(nameof(plainBytes));
RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyPemToPublicKeyParameters(publicKeyBytes);
RsaKeyParameters rsaPublicKeyParams = ParsePublicKeyToParameters(publicKeyBytes);
return EncryptWithECB(rsaPublicKeyParams, plainBytes, paddingMode);
}
/// <summary>
/// 使用公钥基于 ECB 模式加密数据。
/// </summary>
/// <param name="publicKey">PKCS#8 公钥PEM 格式)。</param>
/// <param name="plainText">待加密的文本数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/></param>
/// <returns>经 Base64 编码的加密数据。</returns>
public static string EncryptWithECB(string publicKey, string plainText, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1)
/// <param name="publicKeyPem">PKCS#1/PKCS#8 公钥PEM 格式)。</param>
/// <param name="plainData">待加密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/></param>
/// <returns>经 Base64 编码的加密数据。</returns>
public static EncodedString EncryptWithECB(string publicKeyPem, string plainData, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
{
if (publicKey is null) throw new ArgumentNullException(nameof(publicKey));
if (plainText is null) throw new ArgumentNullException(nameof(plainText));
if (publicKeyPem is null) throw new ArgumentNullException(nameof(publicKeyPem));
if (plainData is null) throw new ArgumentNullException(nameof(plainData));
byte[] publicKeyBytes = ConvertPublicKeyPkcs8PemToByteArray(publicKey);
byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
byte[] publicKeyBytes = ConvertPublicKeyPemToByteArray(publicKeyPem);
byte[] plainBytes = EncodedString.FromLiteralString(plainData);
byte[] cipherBytes = EncryptWithECB(publicKeyBytes, plainBytes, paddingMode);
return Convert.ToBase64String(cipherBytes);
return EncodedString.ToBase64String(cipherBytes);
}
/// <summary>
/// 使用证书基于 ECB 模式加密数据。
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="plainText">待加密的文本数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1"/></param>
/// <returns>经 Base64 编码的加密数据。</returns>
public static string EncryptWithECBByCertificate(string certificate, string plainText, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1)
/// <param name="certificatePem">证书PEM 格式)。</param>
/// <param name="plainData">待加密的数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_OAEPWITHSHA1ANDMGF1"/></param>
/// <returns>经 Base64 编码的加密数据。</returns>
public static EncodedString EncryptWithECBByCertificate(string certificatePem, string plainData, string paddingMode = PADDING_MODE_OAEPWITHSHA1ANDMGF1)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
string publicKey = ExportPublicKeyFromCertificate(certificate);
return EncryptWithECB(publicKey, plainText, paddingMode);
string publicKeyPem = ExportPublicKeyFromCertificate(certificatePem);
return EncryptWithECB(publicKeyPem, plainData, paddingMode);
}
/// <summary>
@ -259,7 +335,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// 转为 -----BEGIN PUBLIC KEY----- ..... -----END PUBLIC KEY-----
/// </para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="certificate">证书内容PEM 格式)。</param>
/// <returns>PKCS#8 公钥PEM 格式)。</returns>
public static string ExportPublicKeyFromCertificate(string certificate)
{
@ -279,7 +355,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// <para>从 CRT/CER 证书中导出证书序列号。</para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="certificate">证书内容PEM 格式)。</param>
/// <returns>证书序列号。</returns>
public static string ExportSerialNumberFromCertificate(string certificate)
{
@ -290,11 +366,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
}
/// <summary>
/// <para>从 CRT/CER 证书中导出证书颁发时间。</para>
/// <para>从 CRT/CER 证书中导出证书有效期的开始时间。</para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <returns>证书颁发时间。</returns>
public static DateTimeOffset ExportEffectiveTimeFromCertificate(string certificate)
/// <param name="certificate">证书内容PEM 格式)。</param>
/// <returns>证书有效期的开始时间。</returns>
public static DateTimeOffset ExportValidFromDateFromCertificate(string certificate)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
@ -303,11 +379,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
}
/// <summary>
/// <para>从 CRT/CER 证书中导出证书过期时间。</para>
/// <para>从 CRT/CER 证书中导出证书有效期的结束时间。</para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <returns>证书过期时间。</returns>
public static DateTimeOffset ExportExpireTimeFromCertificate(string certificate)
/// <param name="certificate">证书内容PEM 格式)。</param>
/// <returns>证书有效期的结束时间。</returns>
public static DateTimeOffset ExportValidToDateFromCertificate(string certificate)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));

View File

@ -1,39 +1,44 @@
using System;
using System.Security.Cryptography;
using System.Text;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
using SKIT.FlurlHttpClient.Primitives;
/// <summary>
/// SHA-256 算法工具类。
/// </summary>
public static class SHA256Utility
{
/// <summary>
/// 获取 SHA-256 信息摘要
/// 计算 SHA-256 哈希值
/// </summary>
/// <param name="bytes">信息字节数组。</param>
/// <returns>信息摘要字节数组。</returns>
/// <param name="bytes">要计算哈希值的信息字节数组。</param>
/// <returns>哈希值字节数组。</returns>
public static byte[] Hash(byte[] bytes)
{
if (bytes is null) throw new ArgumentNullException(nameof(bytes));
using SHA256 sha = SHA256.Create();
return sha.ComputeHash(bytes);
#if NET5_0_OR_GREATER
return SHA256.HashData(bytes);
#else
using SHA256 sha256 = SHA256.Create();
return sha256.ComputeHash(bytes);
#endif
}
/// <summary>
/// 获取 SHA-256 信息摘要。
/// 计算 SHA-256 哈希值
/// </summary>
/// <param name="message">文本信息。</param>
/// <returns>信息摘要。</returns>
public static string Hash(string message)
/// <param name="message">要计算哈希值的信息。</param>
/// <returns>经过十六进制编码的哈希值。</returns>
public static EncodedString Hash(string message)
{
if (message is null) throw new ArgumentNullException(nameof(message));
byte[] msgBytes = Encoding.UTF8.GetBytes(message);
byte[] msgBytes = EncodedString.FromLiteralString(message);
byte[] hashBytes = Hash(msgBytes);
return BitConverter.ToString(hashBytes).Replace("-", string.Empty);
return EncodedString.ToHexString(hashBytes);
}
}
}

View File

@ -1,13 +1,11 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Org.BouncyCastle.Asn1;
using Org.BouncyCastle.Asn1.GM;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
@ -20,6 +18,8 @@ using Org.BouncyCastle.X509;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
using SKIT.FlurlHttpClient.Primitives;
/// <summary>
/// SM2 算法工具类。
/// <para>此实现遵循国家标准 GM/T 0009-2012 的有关规定。</para>
@ -33,59 +33,51 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
private const int SM2_C3_LENGTH = 32;
private const int SM2_RS_LENGTH = 32;
private static byte[] ConvertPrivateKeyPkcs8PemToByteArray(string privateKey)
private static byte[] ConvertPrivateKeyPemToByteArray(string privateKeyPem)
{
privateKey = privateKey
privateKeyPem = privateKeyPem
.Replace("-----BEGIN PRIVATE KEY-----", string.Empty)
.Replace("-----END PRIVATE KEY-----", string.Empty);
privateKey = Regex.Replace(privateKey, "\\s+", string.Empty);
return Convert.FromBase64String(privateKey);
privateKeyPem = Regex.Replace(privateKeyPem, "\\s+", string.Empty);
return Convert.FromBase64String(privateKeyPem);
}
private static byte[] ConvertPublicKeyPkcs8PemToByteArray(string publicKey)
private static byte[] ConvertPublicKeyPemToByteArray(string publicKeyPem)
{
publicKey = publicKey
publicKeyPem = publicKeyPem
.Replace("-----BEGIN PUBLIC KEY-----", string.Empty)
.Replace("-----END PUBLIC KEY-----", string.Empty);
publicKey = Regex.Replace(publicKey, "\\s+", string.Empty);
return Convert.FromBase64String(publicKey);
publicKeyPem = Regex.Replace(publicKeyPem, "\\s+", string.Empty);
return Convert.FromBase64String(publicKeyPem);
}
private static X509Certificate ConvertCertificatePemToX509(string certificate)
private static X509Certificate ConvertCertificatePemToX509(string certificatePem)
{
using (TextReader sreader = new StringReader(certificate))
using (TextReader sreader = new StringReader(certificatePem))
{
PemReader pemReader = new PemReader(sreader);
return (X509Certificate)pemReader.ReadObject();
}
}
private static ECPrivateKeyParameters ParsePrivateKeyPemToPrivateKeyParameters(string privateKey)
{
byte[] privateKeyBytes = ConvertPrivateKeyPkcs8PemToByteArray(privateKey);
return ParsePrivateKeyPemToPrivateKeyParameters(privateKeyBytes);
}
private static ECPrivateKeyParameters ParsePrivateKeyPemToPrivateKeyParameters(byte[] privateKeyBytes)
private static ECPrivateKeyParameters ParsePrivateKeyToParameters(byte[] privateKeyBytes)
{
return (ECPrivateKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);
}
private static ECPrivateKeyParameters ParseECPrivateKeyToPrivateKeyParameters(string ecPrivateKeyHex)
private static ECPrivateKeyParameters ParseECPrivateKeyToParameters(byte[] ecPrivateKeyBytes)
{
BigInteger ecPrivateKeyParamsD = new BigInteger(ecPrivateKeyHex, 16);
BigInteger ecPrivateKeyParamsD = new BigInteger(Hex.ToHexString(ecPrivateKeyBytes), 16);
return new ECPrivateKeyParameters(ecPrivateKeyParamsD, SM2_DOMAIN_PARAMS);
}
private static ECPublicKeyParameters ParsePublicKeyPemToPublicKeyParameters(byte[] publicKeyBytes)
private static ECPublicKeyParameters ParsePublicKeyToParameters(byte[] publicKeyBytes)
{
return (ECPublicKeyParameters)PublicKeyFactory.CreateKey(publicKeyBytes);
}
private static ECPublicKeyParameters ParseECPublicKeyToPublicKeyParameters(string ecPublicKeyHex)
private static ECPublicKeyParameters ParseECPublicKeyToParameters(byte[] ecPublicKeyBytes)
{
byte[] ecPublicKeyBytes = Hex.Decode(ecPublicKeyHex);
const int KEY_BYTE_LENGTH = 64;
bool unzipped = ecPublicKeyBytes.FirstOrDefault() == 0x04;
@ -287,7 +279,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (uidBytes is null) throw new ArgumentNullException(nameof(uidBytes));
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
ECPrivateKeyParameters sm2PrivateKeyParams = ParsePrivateKeyPemToPrivateKeyParameters(privateKeyBytes);
ECPrivateKeyParameters sm2PrivateKeyParams = ParsePrivateKeyToParameters(privateKeyBytes);
return SignWithSM3(sm2PrivateKeyParams, uidBytes, msgBytes, asn1Encoding);
}
@ -311,27 +303,27 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 使用私钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="privateKey">PKCS#8 私钥PEM 格式)。</param>
/// <param name="message">待签名的文本数据。</param>
/// <param name="privateKeyPem">PKCS#8 私钥PEM 格式)。</param>
/// <param name="message">待签名的数据。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>经 Base64 编码的签名。</returns>
public static string SignWithSM3(string privateKey, string message, bool asn1Encoding = true)
/// <returns>经 Base64 编码的签名。</returns>
public static EncodedString SignWithSM3(string privateKeyPem, string message, bool asn1Encoding = true)
{
if (privateKey is null) throw new ArgumentNullException(nameof(privateKey));
if (privateKeyPem is null) throw new ArgumentNullException(nameof(privateKeyPem));
if (message is null) throw new ArgumentNullException(nameof(message));
byte[] signBytes = SignWithSM3(
privateKeyBytes: ConvertPrivateKeyPkcs8PemToByteArray(privateKey),
msgBytes: Encoding.UTF8.GetBytes(message),
privateKeyBytes: ConvertPrivateKeyPemToByteArray(privateKeyPem),
msgBytes: EncodedString.FromLiteralString(message),
asn1Encoding: asn1Encoding
);
return Convert.ToBase64String(signBytes);
return EncodedString.ToBase64String(signBytes);
}
/// <summary>
/// 使用 EC 十六进制私钥基于 SM3 算法生成签名。
/// 使用 EC 私钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPrivateKeyBytes">EC 私钥字节数。</param>
/// <param name="ecPrivateKeyBytes">EC 私钥字节数。</param>
/// <param name="uidBytes">用户标识符字节数组。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
@ -342,18 +334,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (uidBytes is null) throw new ArgumentNullException(nameof(uidBytes));
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
return SignWithSM3ByECPrivateKey(
ecPrivateKeyHex: Hex.ToHexString(ecPrivateKeyBytes),
uidBytes: uidBytes,
msgBytes: msgBytes,
asn1Encoding: asn1Encoding
);
ECPrivateKeyParameters sm2PrivateKeyParams = ParseECPrivateKeyToParameters(ecPrivateKeyBytes);
return SignWithSM3(sm2PrivateKeyParams, uidBytes, msgBytes, asn1Encoding);
}
/// <summary>
/// 使用 EC 十六进制私钥基于 SM3 算法生成签名。
/// 使用 EC 私钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPrivateKeyBytes">EC 私钥字节数。</param>
/// <param name="ecPrivateKeyBytes">EC 私钥字节数。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>签名字节数组。</returns>
@ -368,34 +356,38 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
}
/// <summary>
/// 使用 EC 十六进制私钥基于 SM3 算法生成签名。
/// 使用 EC 私钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPrivateKeyHex">EC 私钥(十六进制格式)。</param>
/// <param name="encodingECPrivateKey">经过编码后的通常为十六进制EC 私钥。</param>
/// <param name="uidBytes">用户标识符字节数组。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>签名字节数组。</returns>
public static byte[] SignWithSM3ByECPrivateKey(string ecPrivateKeyHex, byte[] uidBytes, byte[] msgBytes, bool asn1Encoding = true)
public static byte[] SignWithSM3ByECPrivateKey(EncodedString encodingECPrivateKey, byte[] uidBytes, byte[] msgBytes, bool asn1Encoding = true)
{
if (ecPrivateKeyHex is null) throw new ArgumentNullException(nameof(ecPrivateKeyHex));
if (encodingECPrivateKey.Value is null) throw new ArgumentNullException(nameof(encodingECPrivateKey));
if (uidBytes is null) throw new ArgumentNullException(nameof(uidBytes));
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
ECPrivateKeyParameters ecPrivateKeyParams = ParseECPrivateKeyToPrivateKeyParameters(ecPrivateKeyHex);
return SignWithSM3(ecPrivateKeyParams, uidBytes, msgBytes, asn1Encoding);
return SignWithSM3ByECPrivateKey(
ecPrivateKeyBytes: EncodedString.FromString(encodingECPrivateKey, fallbackEncodingKind: EncodingKinds.Hex),
uidBytes: uidBytes,
msgBytes: msgBytes,
asn1Encoding: asn1Encoding
);
}
/// <summary>
/// 使用 EC 十六进制私钥基于 SM3 算法生成签名。
/// 使用 EC 私钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPrivateKeyHex">EC 私钥(十六进制格式)。</param>
/// <param name="encodingECPrivateKey">经过编码后的通常为十六进制EC 私钥。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>签名字节数组。</returns>
public static byte[] SignWithSM3ByECPrivateKey(string ecPrivateKeyHex, byte[] msgBytes, bool asn1Encoding = true)
public static byte[] SignWithSM3ByECPrivateKey(EncodedString encodingECPrivateKey, byte[] msgBytes, bool asn1Encoding = true)
{
return SignWithSM3ByECPrivateKey(
ecPrivateKeyHex: ecPrivateKeyHex,
encodingECPrivateKey: encodingECPrivateKey,
uidBytes: SM2_DEFAULT_UID,
msgBytes: msgBytes,
asn1Encoding: asn1Encoding
@ -405,10 +397,10 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 使用公钥基于 SM3 算法验证签名。
/// </summary>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数。</param>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数。</param>
/// <param name="uidBytes">用户标识符字节数组。</param>
/// <param name="msgBytes">待验证的数据字节数。</param>
/// <param name="signBytes">待验证的签名字节数据。</param>
/// <param name="msgBytes">待验证的数据字节数。</param>
/// <param name="signBytes">签名字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>验证结果。</returns>
public static bool VerifyWithSM3(byte[] publicKeyBytes, byte[] uidBytes, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
@ -418,16 +410,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
if (signBytes is null) throw new ArgumentNullException(nameof(signBytes));
ECPublicKeyParameters sm2PublicKeyParams = ParsePublicKeyPemToPublicKeyParameters(publicKeyBytes);
ECPublicKeyParameters sm2PublicKeyParams = ParsePublicKeyToParameters(publicKeyBytes);
return VerifyWithSM3(sm2PublicKeyParams, uidBytes, msgBytes, signBytes, asn1Encoding);
}
/// <summary>
/// 使用公钥基于 SM3 算法验证签名。
/// </summary>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数。</param>
/// <param name="msgBytes">待验证的数据字节数。</param>
/// <param name="signBytes">待验证的签名字节数据。</param>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数。</param>
/// <param name="msgBytes">待验证的数据字节数。</param>
/// <param name="signBytes">签名字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>验证结果。</returns>
public static bool VerifyWithSM3(byte[] publicKeyBytes, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
@ -444,21 +436,21 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 使用公钥基于 SM3 算法验证签名。
/// </summary>
/// <param name="publicKey">PKCS#8 公钥PEM 格式)。</param>
/// <param name="message">待验证的文本数据。</param>
/// <param name="signature">经 Base64 编码的待验证的签名。</param>
/// <param name="publicKeyPem">PKCS#8 公钥PEM 格式)。</param>
/// <param name="message">待验证的数据。</param>
/// <param name="encodingSignature">经过编码后的(通常为 Base64签名。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>验证结果。</returns>
public static bool VerifyWithSM3(string publicKey, string message, string signature, bool asn1Encoding = true)
public static bool VerifyWithSM3(string publicKeyPem, string message, EncodedString encodingSignature, bool asn1Encoding = true)
{
if (publicKey is null) throw new ArgumentNullException(nameof(publicKey));
if (publicKeyPem is null) throw new ArgumentNullException(nameof(publicKeyPem));
if (message is null) throw new ArgumentNullException(nameof(message));
if (signature is null) throw new ArgumentNullException(nameof(signature));
if (encodingSignature.Value is null) throw new ArgumentNullException(nameof(encodingSignature));
return VerifyWithSM3(
publicKeyBytes: ConvertPublicKeyPkcs8PemToByteArray(publicKey),
msgBytes: Encoding.UTF8.GetBytes(message),
signBytes: Convert.FromBase64String(signature),
publicKeyBytes: ConvertPublicKeyPemToByteArray(publicKeyPem),
msgBytes: EncodedString.FromLiteralString(message),
signBytes: EncodedString.FromString(encodingSignature, fallbackEncodingKind: EncodingKinds.Base64),
asn1Encoding: asn1Encoding
);
}
@ -466,31 +458,31 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 使用证书基于 SM3 算法验证签名。
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="message">待验证的文本数据。</param>
/// <param name="signature">经 Base64 编码的待验证的签名。</param>
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <param name="message">待验证的数据。</param>
/// <param name="encodingSignature">经过编码后的(通常为 Base64签名。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>验证结果。</returns>
public static bool VerifyWithSM3ByCertificate(string certificate, string message, string signature, bool asn1Encoding = true)
public static bool VerifyWithSM3ByCertificate(string certificatePem, string message, EncodedString encodingSignature, bool asn1Encoding = true)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
string publicKey = ExportPublicKeyFromCertificate(certificate);
string publicKeyPem = ExportPublicKeyFromCertificate(certificatePem);
return VerifyWithSM3(
publicKey: publicKey,
publicKeyPem: publicKeyPem,
message: message,
signature: signature,
encodingSignature: encodingSignature,
asn1Encoding: asn1Encoding
);
}
/// <summary>
/// 使用 EC 十六进制公钥基于 SM3 算法生成签名。
/// 使用 EC 公钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPublicKeyBytes">EC 公钥字节数。</param>
/// <param name="ecPublicKeyBytes">EC 公钥字节数。</param>
/// <param name="uidBytes">用户标识符字节数组。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="signBytes">待验证的签名字节数据。</param>
/// <param name="msgBytes">待验证的数据字节数组。</param>
/// <param name="signBytes">签名字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>签名字节数组。</returns>
public static bool VerifyWithSM3ByECPublicKey(byte[] ecPublicKeyBytes, byte[] uidBytes, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
@ -499,21 +491,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (uidBytes is null) throw new ArgumentNullException(nameof(uidBytes));
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
return VerifyWithSM3ByECPublicKey(
ecPublicKeyHex: Hex.ToHexString(ecPublicKeyBytes),
uidBytes: uidBytes,
msgBytes: msgBytes,
signBytes: signBytes,
asn1Encoding: asn1Encoding
);
ECPublicKeyParameters sm2PublicKeyParams = ParseECPublicKeyToParameters(ecPublicKeyBytes);
return VerifyWithSM3(sm2PublicKeyParams, uidBytes, msgBytes, signBytes, asn1Encoding);
}
/// <summary>
/// 使用 EC 十六进制公钥基于 SM3 算法生成签名。
/// 使用 EC 公钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPublicKeyBytes">EC 公钥字节数。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="signBytes">待验证的签名字节数据。</param>
/// <param name="ecPublicKeyBytes">EC 公钥字节数。</param>
/// <param name="msgBytes">待验证的数据字节数组。</param>
/// <param name="signBytes">签名字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>签名字节数组。</returns>
public static bool VerifyWithSM3ByECPublicKey(byte[] ecPublicKeyBytes, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
@ -528,36 +515,41 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
}
/// <summary>
/// 使用 EC 十六进制公钥基于 SM3 算法生成签名。
/// 使用 EC 公钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPublicKeyHex">EC 公钥(十六进制格式)。</param>
/// <param name="encodingECPublicKey">经过编码后的通常为十六进制EC 公钥。</param>
/// <param name="uidBytes">用户标识符字节数组。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="signBytes">待验证的签名字节数据。</param>
/// <param name="msgBytes">待验证的数据字节数组。</param>
/// <param name="signBytes">签名字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>签名字节数组。</returns>
public static bool VerifyWithSM3ByECPublicKey(string ecPublicKeyHex, byte[] uidBytes, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
public static bool VerifyWithSM3ByECPublicKey(EncodedString encodingECPublicKey, byte[] uidBytes, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
{
if (ecPublicKeyHex is null) throw new ArgumentNullException(nameof(ecPublicKeyHex));
if (encodingECPublicKey.Value is null) throw new ArgumentNullException(nameof(encodingECPublicKey));
if (uidBytes is null) throw new ArgumentNullException(nameof(uidBytes));
if (msgBytes is null) throw new ArgumentNullException(nameof(msgBytes));
ECPublicKeyParameters ecPublicKeyParams = ParseECPublicKeyToPublicKeyParameters(ecPublicKeyHex);
return VerifyWithSM3(ecPublicKeyParams, uidBytes, msgBytes, signBytes, asn1Encoding);
return VerifyWithSM3ByECPublicKey(
ecPublicKeyBytes: EncodedString.FromString(encodingECPublicKey, fallbackEncodingKind: EncodingKinds.Hex),
uidBytes: uidBytes,
msgBytes: msgBytes,
signBytes: signBytes,
asn1Encoding: asn1Encoding
);
}
/// <summary>
/// 使用 EC 十六进制公钥基于 SM3 算法生成签名。
/// 使用 EC 公钥基于 SM3 算法生成签名。
/// </summary>
/// <param name="ecPublicKeyHex">EC 公钥(十六进制格式)。</param>
/// <param name="msgBytes">待签名的数据字节数组。</param>
/// <param name="signBytes">待验证的签名字节数据。</param>
/// <param name="encodingECPublicKey">经过编码后的通常为十六进制EC 公钥。</param>
/// <param name="msgBytes">待验证的数据字节数组。</param>
/// <param name="signBytes">签名字节数组。</param>
/// <param name="asn1Encoding">指示签名结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>签名字节数组。</returns>
public static bool VerifyWithSM3ByECPublicKey(string ecPublicKeyHex, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
public static bool VerifyWithSM3ByECPublicKey(EncodedString encodingECPublicKey, byte[] msgBytes, byte[] signBytes, bool asn1Encoding = true)
{
return VerifyWithSM3ByECPublicKey(
ecPublicKeyHex: ecPublicKeyHex,
encodingECPublicKey: encodingECPublicKey,
uidBytes: SM2_DEFAULT_UID,
msgBytes: msgBytes,
signBytes: signBytes,
@ -568,8 +560,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 使用私钥解密数据。
/// </summary>
/// <param name="privateKeyBytes">PKCS#8 私钥字节数。</param>
/// <param name="cipherBytes">待解密的数据字节数。</param>
/// <param name="privateKeyBytes">PKCS#8 私钥字节数。</param>
/// <param name="cipherBytes">待解密的数据字节数。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>解密后的数据字节数组。</returns>
public static byte[] Decrypt(byte[] privateKeyBytes, byte[] cipherBytes, bool asn1Encoding = true)
@ -577,68 +569,68 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (privateKeyBytes is null) throw new ArgumentNullException(nameof(privateKeyBytes));
if (cipherBytes is null) throw new ArgumentNullException(nameof(cipherBytes));
ECPrivateKeyParameters sm2PrivateKeyParams = ParsePrivateKeyPemToPrivateKeyParameters(privateKeyBytes);
ECPrivateKeyParameters sm2PrivateKeyParams = ParsePrivateKeyToParameters(privateKeyBytes);
return Decrypt(sm2PrivateKeyParams, cipherBytes, asn1Encoding);
}
/// <summary>
/// 使用私钥解密数据。
/// </summary>
/// <param name="privateKey">PKCS#8 私钥PEM 格式)。</param>
/// <param name="cipherText">经 Base64 编码的待解密数据。</param>
/// <param name="privateKeyPem">PKCS#8 私钥PEM 格式)。</param>
/// <param name="encodingCipher">经过编码后的(通常为 Base64待解密数据。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>解密后的文本数据。</returns>
public static string Decrypt(string privateKey, string cipherText, bool asn1Encoding = true)
/// <returns>解密后的数据。</returns>
public static EncodedString Decrypt(string privateKeyPem, EncodedString encodingCipher, bool asn1Encoding = true)
{
if (privateKey is null) throw new ArgumentNullException(nameof(privateKey));
if (cipherText is null) throw new ArgumentNullException(nameof(cipherText));
if (privateKeyPem is null) throw new ArgumentNullException(nameof(privateKeyPem));
if (encodingCipher.Value is null) throw new ArgumentNullException(nameof(encodingCipher));
byte[] plainBytes = Decrypt(
privateKeyBytes: ConvertPrivateKeyPkcs8PemToByteArray(privateKey),
cipherBytes: Convert.FromBase64String(cipherText),
privateKeyBytes: ConvertPrivateKeyPemToByteArray(privateKeyPem),
cipherBytes: EncodedString.FromString(encodingCipher, fallbackEncodingKind: EncodingKinds.Base64),
asn1Encoding: asn1Encoding
);
return Encoding.UTF8.GetString(plainBytes);
return EncodedString.ToLiteralString(plainBytes);
}
/// <summary>
/// 使用 EC 十六进制私钥解密数据。
/// 使用 EC 私钥解密数据。
/// </summary>
/// <param name="ecPrivateKeyBytes">EC 私钥字节数。</param>
/// <param name="cipherBytes">待解密的数据字节数。</param>
/// <param name="ecPrivateKeyBytes">EC 私钥字节数。</param>
/// <param name="cipherBytes">待解密的数据字节数。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>解密后的数据字节数组。</returns>
public static byte[] DecryptByECPrivateKey(byte[] ecPrivateKeyBytes, byte[] cipherBytes, bool asn1Encoding = true)
{
if (ecPrivateKeyBytes is null) throw new ArgumentNullException(nameof(ecPrivateKeyBytes));
ECPrivateKeyParameters ecPrivateKeyParams = ParseECPrivateKeyToParameters(ecPrivateKeyBytes);
return Decrypt(ecPrivateKeyParams, cipherBytes, asn1Encoding);
}
/// <summary>
/// 使用 EC 私钥解密数据。
/// </summary>
/// <param name="encodingECPrivateKey">经过编码后的通常为十六进制EC 私钥。</param>
/// <param name="cipherBytes">待解密的数据字节数组。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>解密后的数据。</returns>
public static byte[] DecryptByECPrivateKey(EncodedString encodingECPrivateKey, byte[] cipherBytes, bool asn1Encoding = true)
{
if (encodingECPrivateKey.Value is null) throw new ArgumentNullException(nameof(encodingECPrivateKey));
return DecryptByECPrivateKey(
ecPrivateKeyHex: Hex.ToHexString(ecPrivateKeyBytes),
ecPrivateKeyBytes: EncodedString.FromString(encodingECPrivateKey, fallbackEncodingKind: EncodingKinds.Hex),
cipherBytes: cipherBytes,
asn1Encoding: asn1Encoding
);
}
/// <summary>
/// 使用 EC 十六进制私钥解密数据。
/// </summary>
/// <param name="ecPrivateKeyHex">EC 私钥(十六进制格式)。</param>
/// <param name="cipherBytes">待解密的数据字节数据。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>解密后的文本数据。</returns>
public static byte[] DecryptByECPrivateKey(string ecPrivateKeyHex, byte[] cipherBytes, bool asn1Encoding = true)
{
if (ecPrivateKeyHex is null) throw new ArgumentNullException(nameof(ecPrivateKeyHex));
ECPrivateKeyParameters ecPrivateKeyParams = ParseECPrivateKeyToPrivateKeyParameters(ecPrivateKeyHex);
return Decrypt(ecPrivateKeyParams, cipherBytes, asn1Encoding);
}
/// <summary>
/// 使用公钥加密数据。
/// </summary>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数。</param>
/// <param name="plainBytes">待加密的数据字节数。</param>
/// <param name="publicKeyBytes">PKCS#8 公钥字节数组。</param>
/// <param name="plainBytes">待加密的数据字节数组。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>加密后的数据字节数组。</returns>
public static byte[] Encrypt(byte[] publicKeyBytes, byte[] plainBytes, bool asn1Encoding = true)
@ -646,77 +638,77 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (publicKeyBytes is null) throw new ArgumentNullException(nameof(publicKeyBytes));
if (plainBytes is null) throw new ArgumentNullException(nameof(plainBytes));
ECPublicKeyParameters sm2PublicKeyParams = ParsePublicKeyPemToPublicKeyParameters(publicKeyBytes);
ECPublicKeyParameters sm2PublicKeyParams = ParsePublicKeyToParameters(publicKeyBytes);
return Encrypt(sm2PublicKeyParams, plainBytes, asn1Encoding);
}
/// <summary>
/// 使用公钥加密数据。
/// </summary>
/// <param name="publicKey">PKCS#8 公钥PEM 格式)。</param>
/// <param name="plainText">待加密的文本数据。</param>
/// <param name="publicKeyPem">PKCS#8 公钥PEM 格式)。</param>
/// <param name="plainData">待加密的数据。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>经 Base64 编码的加密数据。</returns>
public static string Encrypt(string publicKey, string plainText, bool asn1Encoding = true)
/// <returns>经 Base64 编码的加密数据。</returns>
public static EncodedString Encrypt(string publicKeyPem, string plainData, bool asn1Encoding = true)
{
if (publicKey is null) throw new ArgumentNullException(nameof(publicKey));
if (plainText is null) throw new ArgumentNullException(nameof(plainText));
if (publicKeyPem is null) throw new ArgumentNullException(nameof(publicKeyPem));
if (plainData is null) throw new ArgumentNullException(nameof(plainData));
byte[] cipherBytes = Encrypt(
publicKeyBytes: ConvertPublicKeyPkcs8PemToByteArray(publicKey),
plainBytes: Encoding.UTF8.GetBytes(plainText),
publicKeyBytes: ConvertPublicKeyPemToByteArray(publicKeyPem),
plainBytes: EncodedString.FromLiteralString(plainData),
asn1Encoding: asn1Encoding
);
return Convert.ToBase64String(cipherBytes);
return EncodedString.ToBase64String(cipherBytes);
}
/// <summary>
/// 使用证书加密数据。
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="plainText">待加密的文本数据。</param>
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <param name="plainData">待加密的数据。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>经 Base64 编码的加密数据。</returns>
public static string EncryptByCertificate(string certificate, string plainText, bool asn1Encoding = true)
/// <returns>经 Base64 编码的加密数据。</returns>
public static EncodedString EncryptByCertificate(string certificatePem, string plainData, bool asn1Encoding = true)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
return Encrypt(
publicKey: ExportPublicKeyFromCertificate(certificate),
plainText: plainText,
publicKeyPem: ExportPublicKeyFromCertificate(certificatePem),
plainData: plainData,
asn1Encoding: asn1Encoding
);
}
/// <summary>
/// 使用 EC 十六进制公钥加密数据。
/// 使用 EC 公钥加密数据。
/// </summary>
/// <param name="ecPublicKeyBytes">EC 公钥字节数。</param>
/// <param name="plainBytes">待加密的数据字节数。</param>
/// <param name="ecPublicKeyBytes">EC 公钥字节数。</param>
/// <param name="plainBytes">待加密的数据字节数。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>加密后的数据字节数组。</returns>
public static byte[] EncryptByECPublicKey(byte[] ecPublicKeyBytes, byte[] plainBytes, bool asn1Encoding = true)
{
return EncryptByECPublicKey(
ecPublicKeyHex: Hex.ToHexString(ecPublicKeyBytes),
plainBytes: plainBytes,
asn1Encoding: asn1Encoding
);
ECPublicKeyParameters ecPublicKeyParams = ParseECPublicKeyToParameters(ecPublicKeyBytes);
return Encrypt(ecPublicKeyParams, plainBytes, asn1Encoding);
}
/// <summary>
/// 使用 EC 十六进制公钥加密数据。
/// 使用 EC 公钥加密数据。
/// </summary>
/// <param name="ecPublicKeyHex">EC 公钥(十六进制格式)。</param>
/// <param name="plainBytes">待加密的数据字节数。</param>
/// <param name="encodingECPublicKey">EC 公钥(十六进制格式)。</param>
/// <param name="plainBytes">待加密的数据字节数。</param>
/// <param name="asn1Encoding">指示加密结果是否为 ASN.1 编码的形式。默认值true</param>
/// <returns>加密后的数据字节数组。</returns>
public static byte[] EncryptByECPublicKey(string ecPublicKeyHex, byte[] plainBytes, bool asn1Encoding = true)
public static byte[] EncryptByECPublicKey(EncodedString encodingECPublicKey, byte[] plainBytes, bool asn1Encoding = true)
{
if (ecPublicKeyHex is null) throw new ArgumentNullException(nameof(ecPublicKeyHex));
if (encodingECPublicKey.Value is null) throw new ArgumentNullException(nameof(encodingECPublicKey));
ECPublicKeyParameters ecPublicKeyParams = ParseECPublicKeyToPublicKeyParameters(ecPublicKeyHex);
return Encrypt(ecPublicKeyParams, plainBytes, asn1Encoding);
return EncryptByECPublicKey(
ecPublicKeyBytes: EncodedString.FromString(encodingECPublicKey, fallbackEncodingKind: EncodingKinds.Hex),
plainBytes: plainBytes,
asn1Encoding: asn1Encoding
);
}
/// <summary>
@ -726,15 +718,15 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// 转为 -----BEGIN PUBLIC KEY----- ..... -----END PUBLIC KEY-----
/// </para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <returns>PKCS#8 公钥PEM 格式)。</returns>
public static string ExportPublicKeyFromCertificate(string certificate)
public static string ExportPublicKeyFromCertificate(string certificatePem)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
using (TextWriter swriter = new StringWriter())
{
X509Certificate x509cert = ConvertCertificatePemToX509(certificate);
X509Certificate x509cert = ConvertCertificatePemToX509(certificatePem);
ECPublicKeyParameters exPublicKeyParams = (ECPublicKeyParameters)x509cert.GetPublicKey();
PemWriter pemWriter = new PemWriter(swriter);
pemWriter.WriteObject(exPublicKeyParams);
@ -746,39 +738,39 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// <para>从 CRT/CER 证书中导出证书序列号。</para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <returns>证书序列号。</returns>
public static string ExportSerialNumberFromCertificate(string certificate)
public static string ExportSerialNumberFromCertificate(string certificatePem)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
X509Certificate x509cert = ConvertCertificatePemToX509(certificate);
X509Certificate x509cert = ConvertCertificatePemToX509(certificatePem);
return x509cert.SerialNumber.ToString(16);
}
/// <summary>
/// <para>从 CRT/CER 证书中导出证书颁发时间。</para>
/// <para>从 CRT/CER 证书中导出证书有效期的开始时间。</para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <returns>证书颁发时间。</returns>
public static DateTimeOffset ExportEffectiveTimeFromCertificate(string certificate)
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <returns>证书有效期的开始时间。</returns>
public static DateTimeOffset ExportValidFromDateFromCertificate(string certificatePem)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
X509Certificate x509cert = ConvertCertificatePemToX509(certificate);
X509Certificate x509cert = ConvertCertificatePemToX509(certificatePem);
return new DateTimeOffset(x509cert.NotBefore);
}
/// <summary>
/// <para>从 CRT/CER 证书中导出证书过期时间。</para>
/// <para>从 CRT/CER 证书中导出证书有效期的结束时间。</para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <returns>证书过期时间。</returns>
public static DateTimeOffset ExportExpireTimeFromCertificate(string certificate)
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <returns>证书有效期的结束时间。</returns>
public static DateTimeOffset ExportValidToDateFromCertificate(string certificatePem)
{
if (certificate is null) throw new ArgumentNullException(nameof(certificate));
if (certificatePem is null) throw new ArgumentNullException(nameof(certificatePem));
X509Certificate x509cert = ConvertCertificatePemToX509(certificate);
X509Certificate x509cert = ConvertCertificatePemToX509(certificatePem);
return new DateTimeOffset(x509cert.NotAfter);
}
@ -789,12 +781,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// 转为 04+X|Y 结构的十六进制字符串。
/// </para>
/// </summary>
/// <param name="certificate">证书PEM 格式)。</param>
/// <param name="certificatePem">证书内容PEM 格式)。</param>
/// <returns>EC 公钥(十六进制格式)。</returns>
public static string ExportECPublicKeyFromCertificate(string certificate)
public static string ExportECPublicKeyFromCertificate(string certificatePem)
{
string publicKey = ExportPublicKeyFromCertificate(certificate);
return ExportECPublicKeyFromPublicKey(publicKey);
string publicKeyPem = ExportPublicKeyFromCertificate(certificatePem);
return ExportECPublicKeyFromPublicKey(publicKeyPem);
}
/// <summary>
@ -804,12 +796,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// 转为 04+X|Y 结构的 130(128+2) 位的十六进制字符串。
/// </para>
/// </summary>
/// <param name="publicKey">PKCS#8 公钥PEM 格式)。</param>
/// <param name="publicKeyPem">PKCS#8 公钥PEM 格式)。</param>
/// <returns>EC 公钥(十六进制格式)。</returns>
public static string ExportECPublicKeyFromPublicKey(string publicKey)
public static string ExportECPublicKeyFromPublicKey(string publicKeyPem)
{
byte[] publicKeyBytes = ConvertPublicKeyPkcs8PemToByteArray(publicKey);
ECPublicKeyParameters sm2PublicKeyParams = ParsePublicKeyPemToPublicKeyParameters(publicKeyBytes);
byte[] publicKeyBytes = ConvertPublicKeyPemToByteArray(publicKeyPem);
ECPublicKeyParameters sm2PublicKeyParams = ParsePublicKeyToParameters(publicKeyBytes);
ECPoint ecPublicKeyPoint = sm2PublicKeyParams.Q;
string ecPublicKeyX = ecPublicKeyPoint.XCoord.ToBigInteger().ToString(16);
string ecPublicKeyY = ecPublicKeyPoint.YCoord.ToBigInteger().ToString(16);
@ -823,11 +815,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// 转为 64 位的十六进制字符串。
/// </para>
/// </summary>
/// <param name="privateKey">PKCS#8 私钥PEM 格式)。</param>
/// <param name="privateKeyPem">PKCS#8 私钥PEM 格式)。</param>
/// <returns>EC 私钥(十六进制格式)。</returns>
public static string ExportECPrivateKeyFromPrivateKey(string privateKey)
public static string ExportECPrivateKeyFromPrivateKey(string privateKeyPem)
{
ECPrivateKeyParameters sm2PrivateKeyParams = ParsePrivateKeyPemToPrivateKeyParameters(privateKey);
byte[] privateKeyBytes = ConvertPrivateKeyPemToByteArray(privateKeyPem);
ECPrivateKeyParameters sm2PrivateKeyParams = ParsePrivateKeyToParameters(privateKeyBytes);
return sm2PrivateKeyParams.D.ToString(16);
}
}

View File

@ -1,19 +1,20 @@
using System;
using System.Text;
using Org.BouncyCastle.Crypto.Digests;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
using SKIT.FlurlHttpClient.Primitives;
/// <summary>
/// SM3 算法工具类。
/// </summary>
public static class SM3Utility
{
/// <summary>
/// 获取 SM3 哈希值。
/// 计算 SM3 哈希值。
/// </summary>
/// <param name="bytes">信息字节数组。</param>
/// <returns>哈希字节数组。</returns>
/// <param name="bytes">要计算哈希值的信息字节数组。</param>
/// <returns>哈希字节数组。</returns>
public static byte[] Hash(byte[] bytes)
{
if (bytes is null) throw new ArgumentNullException(nameof(bytes));
@ -26,17 +27,17 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
}
/// <summary>
/// 获取 SM3 哈希值。
/// 计算 SM3 哈希值。
/// </summary>
/// <param name="message">文本信息。</param>
/// <returns>哈希值。</returns>
public static string Hash(string message)
/// <param name="message">要计算哈希值的信息。</param>
/// <returns>经过十六进制编码的哈希值。</returns>
public static EncodedString Hash(string message)
{
if (message is null) throw new ArgumentNullException(nameof(message));
byte[] msgBytes = Encoding.UTF8.GetBytes(message);
byte[] msgBytes = EncodedString.FromLiteralString(message);
byte[] hashBytes = Hash(msgBytes);
return BitConverter.ToString(hashBytes).Replace("-", string.Empty);
return EncodedString.ToHexString(hashBytes);
}
}
}

View File

@ -1,29 +1,32 @@
using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Security;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
using SKIT.FlurlHttpClient.Primitives;
/// <summary>
/// SM4 算法工具类。
/// </summary>
public static class SM4Utility
{
private const string SM4_CIPHER_ALGORITHM_GCM = "SM4/GCM";
private const string SM4_CIPHER_PADDING_NOPADDING = "NoPadding";
/// <summary>
/// 填充模式NoPadding。
/// </summary>
private const string PADDING_MODE_NOPADDING = "NoPadding";
/// <summary>
/// 基于 GCM 模式解密数据。
/// </summary>
/// <param name="keyBytes">SM4 密钥字节数组。</param>
/// <param name="nonceBytes">加密使用的初始化向量字节数组。</param>
/// <param name="aadBytes">加密使用的附加数据字节数组。</param>
/// <param name="nonceBytes">初始化向量字节数组。</param>
/// <param name="associatedDataBytes">附加数据字节数组。</param>
/// <param name="cipherBytes">待解密数据字节数组。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="SM4_CIPHER_PADDING_NOPADDING"/></param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_NOPADDING"/></param>
/// <returns>解密后的数据字节数组。</returns>
public static byte[] DecryptWithGCM(byte[] keyBytes, byte[] nonceBytes, byte[]? aadBytes, byte[] cipherBytes, string paddingMode = SM4_CIPHER_PADDING_NOPADDING)
public static byte[] DecryptWithGCM(byte[] keyBytes, byte[] nonceBytes, byte[]? associatedDataBytes, byte[] cipherBytes, string paddingMode = PADDING_MODE_NOPADDING)
{
const int KEY_LENGTH_BYTE = 16;
const int NONCE_LENGTH_BYTE = 12;
@ -36,12 +39,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
if (cipherBytes is null) throw new ArgumentNullException(nameof(cipherBytes));
if (cipherBytes.Length < TAG_LENGTH_BYTE) throw new ArgumentException($"Invalid cipher byte length (expected: more than {TAG_LENGTH_BYTE}, actual: {cipherBytes.Length}).", nameof(cipherBytes));
IBufferedCipher cipher = CipherUtilities.GetCipher(string.Format("{0}/{1}", SM4_CIPHER_ALGORITHM_GCM, paddingMode));
IBufferedCipher cipher = CipherUtilities.GetCipher($"SM4/GCM/{paddingMode}");
ICipherParameters cipherParams = new AeadParameters(
new KeyParameter(keyBytes),
TAG_LENGTH_BYTE * 8,
nonceBytes,
aadBytes
associatedDataBytes
);
cipher.Init(false, cipherParams);
byte[] plainBytes = new byte[cipher.GetOutputSize(cipherBytes.Length)];
@ -53,26 +56,26 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 基于 GCM 模式解密数据。
/// </summary>
/// <param name="key">SM4 密钥。</param>
/// <param name="nonce">加密使用的初始化向量。</param>
/// <param name="aad">加密使用的附加数据包。</param>
/// <param name="cipherText">经 Base64 编码后的待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="SM4_CIPHER_PADDING_NOPADDING"/></param>
/// <returns>解密后的文本数据。</returns>
public static string DecryptWithGCM(string key, string nonce, string? aad, string cipherText, string paddingMode = SM4_CIPHER_PADDING_NOPADDING)
/// <param name="encodingKey">经过编码后的(通常为 Base64SM4 密钥。</param>
/// <param name="encodingNonce">经过编码后的(通常为 Base64初始化向量。</param>
/// <param name="encodingAssociatedData">经过编码后的(通常为 Base64附加数据。</param>
/// <param name="encodingCipher">经过编码后的(通常为 Base64待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="PADDING_MODE_NOPADDING"/></param>
/// <returns>解密后的数据。</returns>
public static EncodedString DecryptWithGCM(EncodedString encodingKey, EncodedString encodingNonce, EncodedString encodingAssociatedData, EncodedString encodingCipher, string paddingMode = PADDING_MODE_NOPADDING)
{
if (key is null) throw new ArgumentNullException(nameof(key));
if (nonce is null) throw new ArgumentNullException(nameof(nonce));
if (cipherText is null) throw new ArgumentNullException(nameof(cipherText));
if (encodingKey.Value is null) throw new ArgumentNullException(nameof(encodingKey));
if (encodingNonce.Value is null) throw new ArgumentNullException(nameof(encodingNonce));
if (encodingCipher.Value is null) throw new ArgumentNullException(nameof(encodingCipher));
byte[] plainBytes = DecryptWithGCM(
keyBytes: Encoding.UTF8.GetBytes(key),
nonceBytes: Encoding.UTF8.GetBytes(nonce),
aadBytes: aad is null ? null : Encoding.UTF8.GetBytes(aad),
cipherBytes: Convert.FromBase64String(cipherText),
keyBytes: EncodedString.FromString(encodingKey, fallbackEncodingKind: EncodingKinds.Base64),
nonceBytes: EncodedString.FromString(encodingNonce, fallbackEncodingKind: EncodingKinds.Base64),
associatedDataBytes: encodingAssociatedData.Value is not null ? EncodedString.FromString(encodingAssociatedData, fallbackEncodingKind: EncodingKinds.Base64) : null,
cipherBytes: EncodedString.FromString(encodingCipher, fallbackEncodingKind: EncodingKinds.Base64),
paddingMode: paddingMode
);
return Encoding.UTF8.GetString(plainBytes);
return EncodedString.ToLiteralString(plainBytes);
}
}
}

View File

@ -10,6 +10,8 @@ using Flurl.Http;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using SKIT.FlurlHttpClient.Primitives;
public partial class TestCase_RequestEncryptionTests
{
// 此处测试的 RSA/SM2 证书/公钥/私钥是自签名生成的,仅供执行 RSA/SM2 相关的单元测试,不能用于调用微信支付 API。
@ -48,14 +50,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteModifyApplyForSubMerchantSettlementAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -65,14 +67,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteModifyApplyForSubMerchantSettlementAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -137,14 +139,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateApplyForSubjectApplymentAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -154,14 +156,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateApplyForSubjectApplymentAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -256,14 +258,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateApplyForSubMerchantApplymentAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -273,14 +275,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateApplyForSubMerchantApplymentAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -315,14 +317,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateBrandProfitSharingOrderAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -332,14 +334,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateBrandProfitSharingOrderAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -368,14 +370,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteQueryCapitalBanksByBankAccountAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -385,14 +387,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteQueryCapitalBanksByBankAccountAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -424,14 +426,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher, "Pkcs1Padding"));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher, Utilities.RSAUtility.PADDING_MODE_PKCS1)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteVerifyHKCustomsCertificateAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher, "Pkcs1Padding"));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher, Utilities.RSAUtility.PADDING_MODE_PKCS1)!);
}
}
@ -441,14 +443,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteVerifyHKCustomsCertificateAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -537,14 +539,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateEcommerceApplymentAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -554,14 +556,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateEcommerceApplymentAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -596,14 +598,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateEcommerceProfitSharingOrderAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -613,14 +615,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateEcommerceProfitSharingOrderAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -649,14 +651,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteAddEcommerceProfitSharingReceiverAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -666,14 +668,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteAddEcommerceProfitSharingReceiverAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -717,14 +719,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecutePresignEducationSchoolPayContractAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -734,14 +736,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecutePresignEducationSchoolPayContractAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -770,14 +772,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteImportMarketingMemberCardOpenCardPhoneAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -787,14 +789,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteImportMarketingMemberCardOpenCardPhoneAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -826,14 +828,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteUploadMarketingShoppingReceiptAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -844,14 +846,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteUploadMarketingShoppingReceiptAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -898,14 +900,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateMerchantOperateRiskWithdrawlApplyAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -915,14 +917,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateMerchantOperateRiskWithdrawlApplyAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -954,14 +956,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateMerchantRiskManageTradeUnionInformationReportAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -971,14 +973,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateMerchantRiskManageTradeUnionInformationReportAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1016,14 +1018,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher, "Pkcs1Padding"));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher, Utilities.RSAUtility.PADDING_MODE_PKCS1)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteAddHKSubMerchantAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher, "Pkcs1Padding"));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher, Utilities.RSAUtility.PADDING_MODE_PKCS1)!);
}
}
@ -1033,14 +1035,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteAddHKSubMerchantAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1075,14 +1077,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateNewTaxControlFapiaoApplicationAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1092,14 +1094,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateNewTaxControlFapiaoApplicationAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1134,14 +1136,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateNewTaxControlFapiaoApplicationCardAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1151,14 +1153,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateNewTaxControlFapiaoApplicationCardAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1190,14 +1192,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecutePreorderPayrollCardAuthenticationAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1207,14 +1209,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecutePreorderPayrollCardAuthenticationAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1246,14 +1248,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreatePayrollCardTokenAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1263,14 +1265,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreatePayrollCardTokenAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1305,14 +1307,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateProfitSharingOrderAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1322,14 +1324,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var reqB2 = GenerateMockRequestModel();
await client.ExecuteCreateProfitSharingOrderAsync(reqB2);
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1358,14 +1360,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteAddProfitSharingReceiverAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1375,14 +1377,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteAddProfitSharingReceiverAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1414,14 +1416,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var reqA1 = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(reqA1);
AssertMockRequestModel(reqA1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqA1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var reqB1 = GenerateMockRequestModel();
await client.ExecuteCreateRefundDomesticAbnormalRefundApplyAsync(reqB1);
AssertMockRequestModel(reqB1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqB1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1431,14 +1433,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var reqA2 = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(reqA2);
AssertMockRequestModel(reqA2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqA2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var reqB2 = GenerateMockRequestModel();
await client.ExecuteCreateRefundDomesticAbnormalRefundApplyAsync(reqB2);
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1470,14 +1472,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var reqA1 = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(reqA1);
AssertMockRequestModel(reqA1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqA1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var reqB1 = GenerateMockRequestModel();
await client.ExecuteCreateSmartGuideAsync(reqB1);
AssertMockRequestModel(reqB1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqB1, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1487,14 +1489,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var reqA2 = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(reqA2);
AssertMockRequestModel(reqA2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqA2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var reqB2 = GenerateMockRequestModel();
await client.ExecuteCreateSmartGuideAsync(reqB2);
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(reqB2, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1523,14 +1525,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteQuerySmartGuidesAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1540,14 +1542,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteQuerySmartGuidesAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1579,14 +1581,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteUpdateSmartGuideAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1596,14 +1598,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteUpdateSmartGuideAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1635,14 +1637,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteUpdateTaxiInvoiceDriverAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1652,14 +1654,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteUpdateTaxiInvoiceDriverAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1697,14 +1699,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateTransferBatchAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1714,14 +1716,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecuteCreateTransferBatchAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}
@ -1759,14 +1761,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseRSA(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecutePreopenVehicleETCAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
@ -1776,14 +1778,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
var request = GenerateMockRequestModel();
client.EncryptRequestSensitiveProperty(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
using (var client = CreateMockClientUseSM2(autoEncrypt: true))
{
var request = GenerateMockRequestModel();
await client.ExecutePreopenVehicleETCAsync(request);
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipher));
AssertMockRequestModel(request, (cipher) => Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipher)!);
}
}
}

View File

@ -1,7 +1,6 @@
using System;
using System.Net;
using System.Net.Http;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
@ -10,6 +9,7 @@ using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using SKIT.FlurlHttpClient.Internal;
using SKIT.FlurlHttpClient.Primitives;
public partial class TestCase_ResponseDecryptionTests
{
@ -47,7 +47,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -55,7 +55,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -69,7 +69,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -77,7 +77,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -202,7 +202,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -210,7 +210,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -224,7 +224,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -232,7 +232,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -269,7 +269,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -277,7 +277,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -291,7 +291,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -299,7 +299,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -336,7 +336,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -344,7 +344,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -358,7 +358,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -366,7 +366,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -404,7 +404,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain, "Pkcs1Padding"));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain, Utilities.RSAUtility.PADDING_MODE_PKCS1)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -412,7 +412,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain, "Pkcs1Padding"))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain, Utilities.RSAUtility.PADDING_MODE_PKCS1)!)
)
))
{
@ -426,7 +426,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -434,7 +434,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -471,7 +471,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -479,7 +479,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -493,7 +493,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -501,7 +501,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -532,7 +532,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -540,7 +540,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -554,7 +554,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -562,7 +562,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -604,7 +604,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -612,7 +612,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -626,7 +626,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -634,7 +634,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -667,7 +667,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -675,7 +675,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -689,7 +689,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -697,7 +697,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -728,7 +728,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -736,7 +736,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -750,7 +750,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -758,7 +758,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -789,7 +789,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -797,7 +797,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -811,7 +811,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -819,7 +819,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -856,7 +856,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -864,7 +864,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -878,7 +878,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -886,7 +886,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -925,7 +925,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -933,7 +933,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -947,7 +947,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -955,7 +955,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -986,7 +986,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -994,7 +994,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -1008,7 +1008,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -1016,7 +1016,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{
@ -1047,7 +1047,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseRSA(autoDecrypt: false))
{
var request = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain));
var request = GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(request);
AssertMockResponseModel(request);
}
@ -1055,7 +1055,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseRSA(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plain)!)
)
))
{
@ -1069,7 +1069,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using (var client = CreateMockClientUseSM2(autoDecrypt: false))
{
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain));
var response = GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!);
client.DecryptResponseSensitiveProperty(response);
AssertMockResponseModel(response);
}
@ -1077,7 +1077,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
using (var client = CreateMockClientUseSM2(
autoDecrypt: true,
mockResponseContent: new SystemTextJsonSerializer().Serialize(
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain))
GenerateMockResponseModel((plain) => Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plain)!)
)
))
{

View File

@ -2,6 +2,8 @@ using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using SKIT.FlurlHttpClient.Primitives;
public class TestCase_ToolsAESUtilityTests
{
[Fact(DisplayName = "测试用例AES-GCM 解密")]
@ -12,7 +14,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
string aad = "certificate";
string cipherText = "x9kkL5w1JuaypcjhrYIP+kVNlN8o8uN4yJyJjy5lg+PyPnQL2Zn//ORaXAyzdaK/WBMVd3u/Y9hLaTBLMyRXzowsrkJ5PT37johye48N7BAJQ0PJwW++d1RdhOOPjoqfmws6rSV5Gv2qhfdKjmpxVjr8xr71dtBt8J2wu+bAV99HHQoAynm/Pp9OQYZgpOQ+1cyFHd43TAxOoFfmixKrXr3HP8lJot0XCUSq4qkr1Hs44FV2KuzntSk8eqKr5N17UcuPF3VYnnnF/AvQ7HuLKWwrHhUbaXfkwy0Q2n36UJMfBj7344S97E8BnS89ojgOPQi+olBPyNgrtDWHgsJAKu7HA6PV/FgmXcrZirje/AH1u25es4z5xItHscm//6rDvALgf7greV5OJzMsSl/KVDtbkjDSzim0j4ZTduIfzh7l6jfOz115ITcNILT9ef2KkcMyBBc89GZlMGeHTbgsBHzGeLawX3dXFjqt5aMnHM3VWCovA2aUM4c//rqkZGf+Va86OEFoJQLiSTFpkOrKxcIxcrbKPLTgiDWRT3wzmnUDg7kSPbluzt3ROvMFq9lB8bO/pBd7TD2w87sfUdKLj69FniX6s37SBeRVhw8GSIvBf5lpLUhqL5zKYlbuAWePuz0wVV4NTtkaVKZlmm8KTODyZDFpsyKPubDDcwT1ftRf5aSVM4x04I/1B7GkNz/TOy+zpJ0h0B7VHdxyO5JYiI/1qsatX/FE2aJdQYMYOtqfDH7ZH5UUKIqo538OKvE2M4MlBR/aVE4z4QDKfE/1kYrOfvVGfDzF/FWHfUrcqB8kdQMvk8vCoM8yYZsX4KE1aoJbNM2pWv2tpr9JE8b/VQgUyHOgPYAha+UOmZki4Sfl9H62687EIWdbM57ZxmwIiBp60SrJLiBfZon9JqXKdtJOKj0CRokQiBnONNXCVerLFeBNQfeKRw8tgJXf+QPohMGYkSDdc8hTgdbmhTwB1Vv01stlYK12QMNRCovlp/fcmpB72Phlq+/3p5pqMzknw+qm5QAz7JnpZJCFHit52gHwAkKRkVPB3HF2rfLrdTYz5c9Bok1ICAY9My47eLFdduIe99V52cjMLQuUmNFBPrDdyZKVqIHJ/wtWO/wIFpAVGSJMHctyEKmeJVc1IQN74Wm00PrpPackHdO3G41bBmkp5pqUdsSgSkwdfNVqv0cMcSe04NrRGNKMcZ7TA/CMaP1YnhxvVE+z8aksJqSJ+gdplvuwl40y5C8UEHeAi1V8Q0Bf4YvYRgOVIWm2Lzjdn2z9PWLGcStUj11/1hthk2li4V3mgm2Cr2IZme2sn4rZmJ6dexGP1nk+ZYOq0xLE8F7oex9gyDN+A/6zHqnuhO/X08qye0gochMr8U89Qvj2c0L3P2mjCea2H1mEriAJPqMPMKIinh1lQJEZufnfCcPxbZLKTtl6zHtHgOztejd1gV/nUyCVKD4MCMfBDy9C/Af8pWx6akOg/QSQNIGA2AI6zprHn9zEjpFIzXJYvruVI22Yt6oF9Xnt7Ki82wRK2M96r4kj6cwSs4exMPGv8fWMrFTm0Br6p6T+HZsxyyn2ChuPIgpfisnce/ZaU/0xCZhK/K79+TK2GeeChq5oEpua/1tx4+kDHi7H9381pLJmy2oXW060c2mmwA9+EpcuwEDhr8fsnghbv41u7b1NhEmWNVUy29Dwaz61PPGUdh5DsvaKLWC+raZ/6UEKPw+tiABJ5o6u2jAWgmEYmmJCKapNgtfPc6D+O0aHH9oqh6u4+8NRAhusPZzDGWBr6AT4pexgWFeEhZhn6bXM9HhpUe0IhOTw5D+tqXrTlNon4kjYibiMUFy1h2YyYS3IEdu1J4xqvo0rFyCxF1C+P6ubc0tClRPkXg==";
string actualPlain = Utilities.AESUtility.DecryptWithGCM(key: key, nonce: nonce, aad: aad, cipherText: cipherText);
string actualPlain = Utilities.AESUtility.DecryptWithGCM(encodingKey: new EncodedString(key, EncodingKinds.Literal), encodingNonce: new EncodedString(nonce, EncodingKinds.Literal), encodingAssociatedData: new EncodedString(aad, EncodingKinds.Literal), encodingCipher: new EncodedString(cipherText, EncodingKinds.Base64))!;
string expectedPlain = "-----BEGIN CERTIFICATE-----\nMIID3DCCAsSgAwIBAgIUGZNrTcamx3sFSJsQli3v9C6gZe8wDQYJKoZIhvcNAQEL\nBQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsT\nFFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3Qg\nQ0EwHhcNMjAwODAxMDczNTE4WhcNMjUwNzMxMDczNTE4WjBuMRgwFgYDVQQDDA9U\nZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRl\nbnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpo\nZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOAYHqxCqaRzoTIvgV\nixaYJJvmvHbiczbx5MQ9XL1ITSFxkTsNsk7RKHnO7eBS5imheJgQwd22Ky+XclSe\n7B4odssu/l/+gHo2gooTYrrCpQrOkpvGMf8R8aI56BQIF+vsomDvVq1NojHV2Fql\njMwFXzhj2EmU6p6gDv9iL7q1NrfnxFx8iJe4OhIB5Ek4qn1xXxrTUhiULd2vXlbI\nXhRetZSNcJsLt5Rw7D7c8F+aX2JchfeqsZECwKW7bSjMbVWWC6M9MgkB/aId8P0y\n7qEiiXFJkfkg1I/E1ud2apopsid5tdCyRRR6+MhhX2EC8S04MN4soUT7haqNNxX2\nrKHnAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DBlBgNVHR8EXjBc\nMFqgWKBWhlRodHRwOi8vZXZjYS5pdHJ1cy5jb20uY24vcHVibGljL2l0cnVzY3Js\nP0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFEMzk3NTQ5ODQ2QzAxQzNFOEVCRDIwDQYJ\nKoZIhvcNAQELBQADggEBAJyg2z4oLQmPfftLQWyzbUc9ONhRMtfA+tVlVBgtLLKn\nWuDlsmEntheM07fu84F4pcfs3yHzjD7pAOFbO4Yt1yhQ50DK35sjbRWepPdWJZLl\nni7KBctcmm0o4zq37oB7vonmBEbFqYs9DaINYOjgI3J25iSBkPVC7dBbvFj2xB0L\ncIcXipq30tDdC/oUem27MNzwZAt49WthKhw6u3HSkcE5cO4LyYTsJhSyG/7LXwvV\nMgX4Jyzo0SSiGOU1/beaZssTVI8sTPJVlHWjhNE3Lc2SaAlKGfGwvt0X3cEZEF+7\noEZIFTkkAF2JhqfnpR3gST0G8Umq1SaVtCPP/zVI8x0=\n-----END CERTIFICATE-----";
Assert.Equal(expectedPlain, actualPlain);

View File

@ -3,6 +3,8 @@ using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using SKIT.FlurlHttpClient.Primitives;
public class TestCase_ToolsRSAUtilityTests
{
// 此处测试的 RSA 证书/公钥/私钥是自签名生成的,仅供执行 RSA 相关的单元测试,不能用于调用微信支付 API。
@ -10,14 +12,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
private const string RSA_CERT_START_DATE = "2021-11-26 02:37:48";
private const string RSA_CERT_END_DATE = "2021-12-26 02:37:48";
private const string RSA_PEM_CERTIFICATE = "-----BEGIN CERTIFICATE-----\nMIIFRzCCAy8CFDBQ9y4tzgPn7+SVV90jHRdmSa+9MA0GCSqGSIb3DQEBCwUAMGAx\nCzAJBgNVBAYTAkNOMREwDwYDVQQIDAhTaGFuZ2hhaTERMA8GA1UEBwwIU2hhbmdo\nYWkxDTALBgNVBAoMBFNLSVQxDTALBgNVBAsMBFNLSVQxDTALBgNVBAMMBFNLSVQw\nHhcNMjExMTI1MTgzNzQ4WhcNMjExMjI1MTgzNzQ4WjBgMQswCQYDVQQGEwJDTjER\nMA8GA1UECAwIU2hhbmdoYWkxETAPBgNVBAcMCFNoYW5naGFpMQ0wCwYDVQQKDART\nS0lUMQ0wCwYDVQQLDARTS0lUMQ0wCwYDVQQDDARTS0lUMIICIjANBgkqhkiG9w0B\nAQEFAAOCAg8AMIICCgKCAgEA52DszUZzPKPo1d9Hi5Hjlu7OINwADaeXifA4rvmJ\nJaA+jm4DCMwrAMzyS12EiW31xCAF8LZ/xkrFHO5CZgvK87Y+kY9DmhvNX6FVYsn4\nay7KER0zo87zqQjC+njUu1rYuKnio7MYb354PitwQ3SWNv2qTCbCNCXTN9pJXNhl\nCudWCEWrNrYc4/hKz3bqu1DjpY0oHuuKPk/iRr2TTUIAwahNkNQheQNB2a8hL7L2\nOG1Sn1vaDWe+5RJYlMRZ3NgYDTqoy8GMs+6q091MQMDlQ90jtW/JEoM5DUyI8zfQ\nfDLGnU7FuY0rrZ/+6OQT/o7ISf0OR5TISS0lqnDN3vVaph0ftDGRdGqJk2SJAHIo\nxp5gt410rfWS9kpSDFJs3Pvt4rtNZBYvkGD8obSm91brAkoX4+u1Y4p1qZpWJ4LI\nKw8oyeieqlLZtF/VGKOtKxe/IKn8GwoQJLx4dUGFOqM7HPwR9cyjMaC1o3V1NQG+\n1wD9TLtGh3WXUFJRYDmePaSp39GFPupTMlPRbD0RK80B6xv2rYTyYyd8s2LN6P6H\nh/nFIkc1rekIf9JhPy0WKzrXdmnfjSHKPxmz0WSYN8FxKasqcJhncOdhLTzzVEhj\n9xHSI8ejP2fJ4v+ARoD3GURPD9H7KMa7xmzRSAZ8A8LM3uvdJNhbKBwWqvo45ncz\n+7cCAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAVTS6oMfDA3XTwEel0BvaXMCdo7yM\ns5ueM87151eywnPlConYDXeqhfF0OCSBnY2g7Fpmn+YAUoa/L+FNOx/gMC9QV/lP\nHhhAcWpiCRy52RX/IyTDxFD6OqtH0BaBtDTb+QBXZuFypMUkPy6EUYs5Cl9qYepy\nHcgGVomx7tcwWcvI4o/KZtj8hXC5wu/k4Y0GGUriTt8xmnJ+RTRedZ6hzAFVHtXm\n/YIT9Lc1IIYZuHVyCbX/HXwa0E4r8lghwZRg94HUvpbfabNA3obt5auwtJUfW1tK\n2ERgFrtBRBWf9EGb8TstXqksqYZ04U4OjLm/3ZJhSSYKNbriRLlSEzAlHikNVW+t\n6cTh+sasrGt/qNIRMs5PiipwmV/T3z1LbyoiU7fXZ4GqiWBnZARFC9KiPPTzLszh\nBKJGYHaC8wkGb3WfNWFBqVRfFL8kdME+shLB8/ETQ31gIFeudnW1QlujJ7ZSZtwz\nxT3HxzZIIbNEqLFP+d37kmuKjRmI4KWc+pKOUw9BOl4g/TJH6ySljSNs8LSDWwQY\n76Dsnr+ovz8ZVLNUCmedZCyumeJo2tLkJmsPo5GuMnXpL94mhqpCoUS4l4JbJl44\nT2lmqp1Ueoz+Qlkqyt2lj3heTv9bvB7NO9KHTsDy1hhWHOG1QyXzajyWETU+1XdW\nx1hGvYxtpQPLUE8=\n-----END CERTIFICATE-----";
private const string RSA_PEM_PUBLIC_KEY = "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA52DszUZzPKPo1d9Hi5Hj\nlu7OINwADaeXifA4rvmJJaA+jm4DCMwrAMzyS12EiW31xCAF8LZ/xkrFHO5CZgvK\n87Y+kY9DmhvNX6FVYsn4ay7KER0zo87zqQjC+njUu1rYuKnio7MYb354PitwQ3SW\nNv2qTCbCNCXTN9pJXNhlCudWCEWrNrYc4/hKz3bqu1DjpY0oHuuKPk/iRr2TTUIA\nwahNkNQheQNB2a8hL7L2OG1Sn1vaDWe+5RJYlMRZ3NgYDTqoy8GMs+6q091MQMDl\nQ90jtW/JEoM5DUyI8zfQfDLGnU7FuY0rrZ/+6OQT/o7ISf0OR5TISS0lqnDN3vVa\nph0ftDGRdGqJk2SJAHIoxp5gt410rfWS9kpSDFJs3Pvt4rtNZBYvkGD8obSm91br\nAkoX4+u1Y4p1qZpWJ4LIKw8oyeieqlLZtF/VGKOtKxe/IKn8GwoQJLx4dUGFOqM7\nHPwR9cyjMaC1o3V1NQG+1wD9TLtGh3WXUFJRYDmePaSp39GFPupTMlPRbD0RK80B\n6xv2rYTyYyd8s2LN6P6Hh/nFIkc1rekIf9JhPy0WKzrXdmnfjSHKPxmz0WSYN8Fx\nKasqcJhncOdhLTzzVEhj9xHSI8ejP2fJ4v+ARoD3GURPD9H7KMa7xmzRSAZ8A8LM\n3uvdJNhbKBwWqvo45ncz+7cCAwEAAQ==\n-----END PUBLIC KEY-----";
private const string RSA_PEM_PRIVATE_KEY = "-----BEGIN PRIVATE KEY-----\n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\nhpUq0eKgdGHc2R4r57soRvGoGy2DtA==\n-----END PRIVATE KEY-----";
private const string RSA_PEM_PUBLIC_KEY_PKCS8 = "-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA52DszUZzPKPo1d9Hi5Hj\nlu7OINwADaeXifA4rvmJJaA+jm4DCMwrAMzyS12EiW31xCAF8LZ/xkrFHO5CZgvK\n87Y+kY9DmhvNX6FVYsn4ay7KER0zo87zqQjC+njUu1rYuKnio7MYb354PitwQ3SW\nNv2qTCbCNCXTN9pJXNhlCudWCEWrNrYc4/hKz3bqu1DjpY0oHuuKPk/iRr2TTUIA\nwahNkNQheQNB2a8hL7L2OG1Sn1vaDWe+5RJYlMRZ3NgYDTqoy8GMs+6q091MQMDl\nQ90jtW/JEoM5DUyI8zfQfDLGnU7FuY0rrZ/+6OQT/o7ISf0OR5TISS0lqnDN3vVa\nph0ftDGRdGqJk2SJAHIoxp5gt410rfWS9kpSDFJs3Pvt4rtNZBYvkGD8obSm91br\nAkoX4+u1Y4p1qZpWJ4LIKw8oyeieqlLZtF/VGKOtKxe/IKn8GwoQJLx4dUGFOqM7\nHPwR9cyjMaC1o3V1NQG+1wD9TLtGh3WXUFJRYDmePaSp39GFPupTMlPRbD0RK80B\n6xv2rYTyYyd8s2LN6P6Hh/nFIkc1rekIf9JhPy0WKzrXdmnfjSHKPxmz0WSYN8Fx\nKasqcJhncOdhLTzzVEhj9xHSI8ejP2fJ4v+ARoD3GURPD9H7KMa7xmzRSAZ8A8LM\n3uvdJNhbKBwWqvo45ncz+7cCAwEAAQ==\n-----END PUBLIC KEY-----";
private const string RSA_PEM_PUBLIC_KEY_PKCS1 = "-----BEGIN RSA PUBLIC KEY-----\nMIICCgKCAgEA52DszUZzPKPo1d9Hi5Hjlu7OINwADaeXifA4rvmJJaA+jm4DCMwr\nAMzyS12EiW31xCAF8LZ/xkrFHO5CZgvK87Y+kY9DmhvNX6FVYsn4ay7KER0zo87z\nqQjC+njUu1rYuKnio7MYb354PitwQ3SWNv2qTCbCNCXTN9pJXNhlCudWCEWrNrYc\n4/hKz3bqu1DjpY0oHuuKPk/iRr2TTUIAwahNkNQheQNB2a8hL7L2OG1Sn1vaDWe+\n5RJYlMRZ3NgYDTqoy8GMs+6q091MQMDlQ90jtW/JEoM5DUyI8zfQfDLGnU7FuY0r\nrZ/+6OQT/o7ISf0OR5TISS0lqnDN3vVaph0ftDGRdGqJk2SJAHIoxp5gt410rfWS\n9kpSDFJs3Pvt4rtNZBYvkGD8obSm91brAkoX4+u1Y4p1qZpWJ4LIKw8oyeieqlLZ\ntF/VGKOtKxe/IKn8GwoQJLx4dUGFOqM7HPwR9cyjMaC1o3V1NQG+1wD9TLtGh3WX\nUFJRYDmePaSp39GFPupTMlPRbD0RK80B6xv2rYTyYyd8s2LN6P6Hh/nFIkc1rekI\nf9JhPy0WKzrXdmnfjSHKPxmz0WSYN8FxKasqcJhncOdhLTzzVEhj9xHSI8ejP2fJ\n4v+ARoD3GURPD9H7KMa7xmzRSAZ8A8LM3uvdJNhbKBwWqvo45ncz+7cCAwEAAQ==\n-----END RSA PUBLIC KEY-----\r\n";
private const string RSA_PEM_PRIVATE_KEY_PKCS8 = "-----BEGIN PRIVATE KEY-----\n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\nhpUq0eKgdGHc2R4r57soRvGoGy2DtA==\n-----END PRIVATE KEY-----";
private const string RSA_PEM_PRIVATE_KEY_PKCS1 = "-----BEGIN RSA PRIVATE KEY-----\n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\n-----END RSA PRIVATE KEY-----\r\n";
[Fact(DisplayName = "测试用例:从 RSA 证书中导出公钥")]
public void TestRSAExportPublicKeyFromCertificate()
{
string actualPublicKey = Utilities.RSAUtility.ExportPublicKeyFromCertificate(RSA_PEM_CERTIFICATE).Replace("\r", "").Replace("\n", "");
string expectedPublicKey = RSA_PEM_PUBLIC_KEY.Replace("\r", "").Replace("\n", "");
string expectedPublicKey = RSA_PEM_PUBLIC_KEY_PKCS8.Replace("\r", "").Replace("\n", "");
Assert.Equal(expectedPublicKey, actualPublicKey, ignoreLineEndingDifferences: true);
}
@ -31,19 +35,19 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
Assert.Equal(expectedSerialNumber, actualSerialNumber, ignoreCase: true);
}
[Fact(DisplayName = "测试用例:从 RSA 证书中导出证书颁发时间")]
public void TestRSAExportEffectiveTimeFromCertificate()
[Fact(DisplayName = "测试用例:从 RSA 证书中导出证书有效期的开始时间")]
public void TestRSAExportValidFromDateFromCertificate()
{
DateTimeOffset actualEffectiveTime = Utilities.RSAUtility.ExportEffectiveTimeFromCertificate(RSA_PEM_CERTIFICATE);
DateTimeOffset actualEffectiveTime = Utilities.RSAUtility.ExportValidFromDateFromCertificate(RSA_PEM_CERTIFICATE);
DateTimeOffset expectedEffectiveTime = DateTimeOffset.Parse(RSA_CERT_START_DATE);
Assert.Equal(expectedEffectiveTime, actualEffectiveTime);
}
[Fact(DisplayName = "测试用例:从 RSA 证书中导出证书过期时间")]
public void TestRSAExportExpireTimeFromCertificate()
[Fact(DisplayName = "测试用例:从 RSA 证书中导出证书有效期的结束时间")]
public void TestRSAExportValidToDateFromCertificate()
{
DateTimeOffset actualExpireTime = Utilities.RSAUtility.ExportExpireTimeFromCertificate(RSA_PEM_CERTIFICATE);
DateTimeOffset actualExpireTime = Utilities.RSAUtility.ExportValidToDateFromCertificate(RSA_PEM_CERTIFICATE);
DateTimeOffset expectedExpireTime = DateTimeOffset.Parse(RSA_CERT_END_DATE);
Assert.Equal(expectedExpireTime, actualExpireTime);
@ -53,11 +57,14 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
public void TestRSASignatureSHA256WithRSASign()
{
string msgText = "SHA256WithRSASignTest";
string actualSign = Utilities.RSAUtility.SignWithSHA256(RSA_PEM_PRIVATE_KEY, msgText);
string actualSignByPrivateKeyPkcs8 = Utilities.RSAUtility.Sign(RSA_PEM_PRIVATE_KEY_PKCS8, msgText)!;
string actualSignByPrivateKeyPkcs1 = Utilities.RSAUtility.Sign(RSA_PEM_PRIVATE_KEY_PKCS1, msgText)!;
string expectedSign = "EzeVEIoBhzOhXpwbXdJjIuGIGRc6ArKO7sVo2fuAdzYTDgorAEufEnw7lPPXV1GTfFcHOnsAJH9kGJmg7Orwlkh7x7TyOGrkMEhWGulA9SIdmou4iBsHpIZ/TERSgGt/VTmqmfpkzJqrvbQWIQENwo7Lr6uJSJBND0YT3nIBP8TzbO3cHnQb6chHIBHrDF5vOO7HHu+Cga2MZnAtRizhO8BhK0jOmyro32CgIML3EVX8yuPy0kOk6aN1R8xFblZUD4NU2M6zzQpydmxaHr9B1WNFoMwmpoAS5BuKJMYOHO5cc6DhB+0fAGxaWtKp6759KhKCf8M65zh3WKS4l262SGuWq4qG1+AKf2DOgCon769+A4z8flOmvl0iIwoH9FThGJoP156rpAJW7v/bWputSeC6WToUTBRmGWdwWySVwW5AZ26OAFFWs1CmrGp3jF5E2oUy1mQwgfM0QN6DW+wD769ggIYH9HLHqDHbF5UyF7eNh3s8Qy23xXEKZWNMAJ0IdtdMQ7FRRgLFSCai7HELLlBJSCz7P5WTeYZGQpbvnUShkRvzujjO6XlGiKKI0EwKb121z8N6KRpvs4SnRztWBGoXbzHZgnXKXU/BWWADemqB2cvaT3Bj0k3/N3sea0dAEtlNEklRWoyyNUUlscK9zg4LBlHrhbbFo66uuub8ySo=";
Assert.Equal(expectedSign, actualSign);
Assert.True(Utilities.RSAUtility.VerifyWithSHA256(RSA_PEM_PUBLIC_KEY, msgText, actualSign));
Assert.Equal(expectedSign, actualSignByPrivateKeyPkcs8);
Assert.Equal(expectedSign, actualSignByPrivateKeyPkcs1);
Assert.True(Utilities.RSAUtility.Verify(RSA_PEM_PUBLIC_KEY_PKCS8, msgText, (EncodedString)actualSignByPrivateKeyPkcs8));
Assert.True(Utilities.RSAUtility.Verify(RSA_PEM_PUBLIC_KEY_PKCS1, msgText, (EncodedString)actualSignByPrivateKeyPkcs1));
}
[Fact(DisplayName = "测试用例SHA256WithRSA 签名验证")]
@ -66,30 +73,36 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
string msgText = "SHA256WithRSAVerifyTest";
string signText = "aHX+MrmZHDEraMKBEPV2Vnps1B9b25lGbv/rdppx/S7+oaXtjKJprzCq5H7RCpvrKS3xYIeTEPwQGC3Vots7dCdLi8v8ew1vvtXf8qNAnd7CTMHqu3wSohXzgyASTmNbXE2ml9LbWYPPYMvPJXROQbGVjoOrsErWBPPJYXuO3lIckIfwI05OTdl4H3+BvpD/ZoljRp8Qgo9+paGvarBc++TaAh0FXnQf0TGNFUIeHHiAKBee5oCBTuZZM9J5RPw0oIq/g7Wun+e/zWiwVBPHltOgZrV46uagSAE6nBDHk+hlNxDivCxkJdBVCSIYFFmBXIcnGZ/u4ZfBui/k1jGoKibyvPK4z2+6GSlj41Yo81kuSBfzLiSsx33EPR1eIJJkwDTsvap0ymL9pfIqMiLuiteH5kGmL/dyONy9oAJywLEeITfoVyElM/CY6Dc+xDhRnjN7Hu54meYyXRZrnCtQ3YhzEr1immNBn6npgA/qi9aHsuWFOw8b8aSwOHDHTDmjmvV+axI8CVMrR0MjB9QNCWrKLq2B9iQX9MtLgcUyDsQvzAsxUJm/OEfzUjs9SHvmgmyAvzNAuTdO7wLQ+ZmKg0yZne6nvcrJVvfh3lD5ZPt7NY57Y6OIJluqKUT5H+a3H6W9Q1Z+cBMnHGYaaK7Tv8IcDdEYqTIG8hc5BqjFOzE=";
Assert.True(Utilities.RSAUtility.VerifyWithSHA256(RSA_PEM_PUBLIC_KEY, msgText, signText));
Assert.False(Utilities.RSAUtility.VerifyWithSHA256(RSA_PEM_PUBLIC_KEY, msgText, "FAKE SIGN"));
Assert.True(Utilities.RSAUtility.VerifyWithSHA256ByCertificate(RSA_PEM_CERTIFICATE, msgText, signText));
Assert.False(Utilities.RSAUtility.VerifyWithSHA256ByCertificate(RSA_PEM_CERTIFICATE, msgText, "FAKE SIGN"));
Assert.True(Utilities.RSAUtility.Verify(RSA_PEM_PUBLIC_KEY_PKCS8, msgText, (EncodedString)signText));
Assert.True(Utilities.RSAUtility.Verify(RSA_PEM_PUBLIC_KEY_PKCS1, msgText, (EncodedString)signText));
Assert.False(Utilities.RSAUtility.Verify(RSA_PEM_PUBLIC_KEY_PKCS8, msgText, (EncodedString)"FAKE SIGN"));
Assert.False(Utilities.RSAUtility.Verify(RSA_PEM_PUBLIC_KEY_PKCS1, msgText, (EncodedString)"FAKE SIGN"));
Assert.True(Utilities.RSAUtility.VerifyByCertificate(RSA_PEM_CERTIFICATE, msgText, (EncodedString)signText));
Assert.False(Utilities.RSAUtility.VerifyByCertificate(RSA_PEM_CERTIFICATE, msgText, (EncodedString)"FAKE SIGN"));
}
[Fact(DisplayName = "测试用例:使用 RSA 公钥加密")]
public void TestRSAEncrypt()
{
string plainText = "RsaEncryptTest";
string actualCipherByPublicKey = Utilities.RSAUtility.EncryptWithECB(RSA_PEM_PUBLIC_KEY, plainText);
string actualCipherByCertificate = Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plainText);
string actualCipherByPublicKeyPkcs8 = Utilities.RSAUtility.EncryptWithECB(RSA_PEM_PUBLIC_KEY_PKCS8, plainText)!;
string actualCipherByPublicKeyPkcs1 = Utilities.RSAUtility.EncryptWithECB(RSA_PEM_PUBLIC_KEY_PKCS1, plainText)!;
string actualCipherByCertificate = Utilities.RSAUtility.EncryptWithECBByCertificate(RSA_PEM_CERTIFICATE, plainText)!;
Assert.NotNull(actualCipherByPublicKey);
Assert.NotNull(actualCipherByPublicKeyPkcs8);
Assert.NotNull(actualCipherByPublicKeyPkcs1);
Assert.NotNull(actualCipherByCertificate);
Assert.Equal(plainText, Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, actualCipherByPublicKey));
Assert.Equal(plainText, Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, actualCipherByCertificate));
Assert.Equal(plainText, Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY_PKCS8, (EncodedString)actualCipherByPublicKeyPkcs8));
Assert.Equal(plainText, Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY_PKCS1, (EncodedString)actualCipherByPublicKeyPkcs1));
Assert.Equal(plainText, Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY_PKCS8, (EncodedString)actualCipherByCertificate));
Assert.Equal(plainText, Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY_PKCS1, (EncodedString)actualCipherByCertificate));
}
[Fact(DisplayName = "测试用例:使用 RSA 私钥解密")]
public void TestRSADecrypt()
{
string cipherText = "LXwSqg4jqIv1X8Jx7RAbKw+mc/2SqAfdO4Ytqu09kytzCiDFdIZuJkdo2BQQOoyn/FtCyvn9Loip3VocOuATtsUDo6BmeMJcapl0HfXkyxsYnVRawsq01SPIRz8c83u+K38ZDVjNxEwcwcxH86wMm3PMzLZqISIVrD9sD3an5TfGuS+y/RN8y6W/P7BD/Rpxh0qLJl5B2oPYHOeKK0tdv6GlouUClzxB5tmdK5EKKw0j4WD5qIEwRm8Xzh/V27bt2autzRBbJT47eNypMR5wT7wWm/YwjyDoLLUmuCBaXbWZuqkB0pGS53y3Rdk64LVZ52567hBuQ/JdqMJdCecfy85x+ygnOtCM7bRl/fspU8U5SmwAKohYMc8VH4kRKhxoh8wX9wXCwbngLQ+S50TB3UziY1FmAmWFAI2/fpiyzGJZAVA+mYRCoQAFOksVEuud3ngGkfx2SafJ589IX9z0dnaz1AElaH84LhrOjJyU7dV6E9Su45IegNNai2O8bwN8dliVMPlXZuUAGaZpPLPOxq+hE7GpgNHaVFNye52b7dG3n3mt3hhSwb9AxAyAbSXktBSS/PMOAAS1TxwQ9C/0bKhApUDpjTG8oZBRBVTUHmsX+6/k5+6KSqfOrD88cBDPIhumY6V1h78GtXkFX2lQu9lT2J/fHCrDx39CiRnFAfI=";
string actualPlain = Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY, cipherText);
string actualPlain = Utilities.RSAUtility.DecryptWithECB(RSA_PEM_PRIVATE_KEY_PKCS8, (EncodedString)cipherText)!;
string expectedPlain = "RsaDecryptTest";
Assert.Equal(expectedPlain, actualPlain);

View File

@ -4,6 +4,8 @@ using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using SKIT.FlurlHttpClient.Primitives;
public class TestCase_ToolsSM2UtilityTests
{
// 此处测试的 SM2 证书/公钥/私钥是自签名生成的,仅供执行 SM2 相关的单元测试,不能用于调用微信支付 API。
@ -38,19 +40,19 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
Assert.Equal(expectedSerialNumber, actualSerialNumber, ignoreCase: true);
}
[Fact(DisplayName = "测试用例:从 SM2 证书中导出证书颁发时间")]
public void TestSM2ExportEffectiveTimeFromCertificate()
[Fact(DisplayName = "测试用例:从 SM2 证书中导出证书有效期的开始时间")]
public void TestSM2ExportValidFromDateFromCertificate()
{
DateTimeOffset actualEffectiveTime = Utilities.SM2Utility.ExportEffectiveTimeFromCertificate(SM2_PEM_CERTIFICATE);
DateTimeOffset actualEffectiveTime = Utilities.SM2Utility.ExportValidFromDateFromCertificate(SM2_PEM_CERTIFICATE);
DateTimeOffset expectedEffectiveTime = DateTimeOffset.Parse(SM2_CERT_START_DATE);
Assert.Equal(expectedEffectiveTime, actualEffectiveTime);
}
[Fact(DisplayName = "测试用例:从 SM2 证书中导出证书过期时间")]
public void TestSM2ExportExpireTimeFromCertificate()
[Fact(DisplayName = "测试用例:从 SM2 证书中导出证书有效期的结束时间")]
public void TestSM2ExportValidToDateFromCertificate()
{
DateTimeOffset actualExpireTime = Utilities.SM2Utility.ExportExpireTimeFromCertificate(SM2_PEM_CERTIFICATE);
DateTimeOffset actualExpireTime = Utilities.SM2Utility.ExportValidToDateFromCertificate(SM2_PEM_CERTIFICATE);
DateTimeOffset expectedExpireTime = DateTimeOffset.Parse(SM2_CERT_END_DATE);
Assert.Equal(expectedExpireTime, actualExpireTime);
@ -76,12 +78,12 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
public void TestSM2SignatureSM2WithSM3Sign()
{
string msgText = "SM2WithSM3SignTest";
string actualSignByPrivateKey = Utilities.SM2Utility.SignWithSM3(SM2_PEM_PRIVATE_KEY, msgText);
string actualSignByECPrivateKey = Convert.ToBase64String(Utilities.SM2Utility.SignWithSM3ByECPrivateKey(SM2_HEX_EC_PRIVATE_KEY, Encoding.UTF8.GetBytes(msgText)));
string actualSignByPrivateKey = Utilities.SM2Utility.SignWithSM3(SM2_PEM_PRIVATE_KEY, msgText)!;
string actualSignByECPrivateKey = Convert.ToBase64String(Utilities.SM2Utility.SignWithSM3ByECPrivateKey((EncodedString)SM2_HEX_EC_PRIVATE_KEY, Encoding.UTF8.GetBytes(msgText)));
Assert.NotNull(actualSignByPrivateKey);
Assert.NotNull(actualSignByECPrivateKey);
Assert.True(Utilities.SM2Utility.VerifyWithSM3(SM2_PEM_PUBLIC_KEY, msgText, actualSignByPrivateKey));
Assert.True(Utilities.SM2Utility.VerifyWithSM3(SM2_PEM_PUBLIC_KEY, msgText, (EncodedString)actualSignByPrivateKey));
}
[Fact(DisplayName = "测试用例SM2WithSM3 签名验证")]
@ -90,36 +92,36 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
string msgText = "SM2WithSM3SignTest";
string signText = "MEUCIQCDzgpF2Z//sbFzASVQnwme2phm4ho5cr8/1Pz0+MONTwIgeQvhoWOTk1rngYRSlHeqqwtNFVD/vf3qtgl9mecvERI=";
Assert.True(Utilities.SM2Utility.VerifyWithSM3(SM2_PEM_PUBLIC_KEY, msgText, signText));
Assert.False(Utilities.SM2Utility.VerifyWithSM3(SM2_PEM_PUBLIC_KEY, msgText, "FAKE SIGN"));
Assert.True(Utilities.SM2Utility.VerifyWithSM3ByCertificate(SM2_PEM_CERTIFICATE, msgText, signText));
Assert.False(Utilities.SM2Utility.VerifyWithSM3ByCertificate(SM2_PEM_CERTIFICATE, msgText, "FAKE SIGN"));
Assert.True(Utilities.SM2Utility.VerifyWithSM3ByECPublicKey(SM2_HEX_EC_PUBLIC_KEY, Encoding.UTF8.GetBytes(msgText), Convert.FromBase64String("MEUCIQCDzgpF2Z//sbFzASVQnwme2phm4ho5cr8/1Pz0+MONTwIgeQvhoWOTk1rngYRSlHeqqwtNFVD/vf3qtgl9mecvERI=")));
Assert.False(Utilities.SM2Utility.VerifyWithSM3ByECPublicKey(SM2_HEX_EC_PUBLIC_KEY, Encoding.UTF8.GetBytes(msgText), Encoding.UTF8.GetBytes("FAKE SIGN")));
Assert.True(Utilities.SM2Utility.VerifyWithSM3(SM2_PEM_PUBLIC_KEY, msgText, (EncodedString)signText));
Assert.False(Utilities.SM2Utility.VerifyWithSM3(SM2_PEM_PUBLIC_KEY, msgText, (EncodedString)"FAKE SIGN"));
Assert.True(Utilities.SM2Utility.VerifyWithSM3ByCertificate(SM2_PEM_CERTIFICATE, msgText, (EncodedString)signText));
Assert.False(Utilities.SM2Utility.VerifyWithSM3ByCertificate(SM2_PEM_CERTIFICATE, msgText, (EncodedString)"FAKE SIGN"));
Assert.True(Utilities.SM2Utility.VerifyWithSM3ByECPublicKey((EncodedString)SM2_HEX_EC_PUBLIC_KEY, Encoding.UTF8.GetBytes(msgText), Convert.FromBase64String("MEUCIQCDzgpF2Z//sbFzASVQnwme2phm4ho5cr8/1Pz0+MONTwIgeQvhoWOTk1rngYRSlHeqqwtNFVD/vf3qtgl9mecvERI=")));
Assert.False(Utilities.SM2Utility.VerifyWithSM3ByECPublicKey((EncodedString)SM2_HEX_EC_PUBLIC_KEY, Encoding.UTF8.GetBytes(msgText), Encoding.UTF8.GetBytes("FAKE SIGN")));
}
[Fact(DisplayName = "测试用例:使用 SM2 公钥加密")]
public void TestSM2Encrypt()
{
string plainText = "SM2EncryptTest";
string actualCipherByPublicKey = Utilities.SM2Utility.Encrypt(SM2_PEM_PUBLIC_KEY, plainText);
string actualCipherByCertificate = Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plainText);
string actualCipherByECPublicKey = Convert.ToBase64String(Utilities.SM2Utility.EncryptByECPublicKey(SM2_HEX_EC_PUBLIC_KEY, Encoding.UTF8.GetBytes(plainText)));
string actualCipherByPublicKey = Utilities.SM2Utility.Encrypt(SM2_PEM_PUBLIC_KEY, plainText)!;
string actualCipherByCertificate = Utilities.SM2Utility.EncryptByCertificate(SM2_PEM_CERTIFICATE, plainText)!;
string actualCipherByECPublicKey = Convert.ToBase64String(Utilities.SM2Utility.EncryptByECPublicKey((EncodedString)SM2_HEX_EC_PUBLIC_KEY, Encoding.UTF8.GetBytes(plainText)));
Assert.NotNull(actualCipherByPublicKey);
Assert.NotNull(actualCipherByCertificate);
Assert.NotNull(actualCipherByECPublicKey);
Assert.Equal(plainText, Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, actualCipherByPublicKey));
Assert.Equal(plainText, Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, actualCipherByCertificate));
Assert.Equal(plainText, Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, actualCipherByECPublicKey));
Assert.Equal(plainText, Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)actualCipherByPublicKey));
Assert.Equal(plainText, Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)actualCipherByCertificate));
Assert.Equal(plainText, Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)actualCipherByECPublicKey));
}
[Fact(DisplayName = "测试用例:使用 SM2 私钥解密")]
public void TestSM2Decrypt()
{
string cipherText = "MHYCIGJ7gjFjd6U7kOj63HLbRgPAn6cVf4eDF4emz9oCX5gKAiBAHmgAvH2WU/2+dyqMK7/Q8eD/Q9LhYFV2gqc+fv7EiAQgiHX2wr7GCnBbAsfR3stJ1i/Csc0Mq3RzVd+ZefVlr7gEDvfJIMlMcs4Q2HoMd8Jk";
string actualPlainByPrivateKey = Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, cipherText);
string actualPlainByECPrivateKey = Encoding.UTF8.GetString(Utilities.SM2Utility.DecryptByECPrivateKey(SM2_HEX_EC_PRIVATE_KEY, Convert.FromBase64String(cipherText)));
string actualPlainByPrivateKey = Utilities.SM2Utility.Decrypt(SM2_PEM_PRIVATE_KEY, (EncodedString)cipherText)!;
string actualPlainByECPrivateKey = Encoding.UTF8.GetString(Utilities.SM2Utility.DecryptByECPrivateKey((EncodedString)SM2_HEX_EC_PRIVATE_KEY, Convert.FromBase64String(cipherText)));
string expectedPlain = "SM2DecryptTest";
Assert.Equal(expectedPlain, actualPlainByPrivateKey);
Assert.Equal(expectedPlain, actualPlainByECPrivateKey);

View File

@ -1,8 +1,9 @@
using System.Text;
using Xunit;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
{
using SKIT.FlurlHttpClient.Primitives;
public class TestCase_ToolsSM4UtilityTests
{
[Fact(DisplayName = "测试用例SM4-GCM 解密")]
@ -13,7 +14,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests
string aad = "certificate";
string cipherText = "fB6kij5HTmN4mXBIu6MaZIjDp8jRt2iziXIGF34yLSHo0Gkt6Y6CgjdWZvCxht2UfC52VbHfeNMS4kOBRtpZ/LO9pIoA/V7Qs/V5RD3iqxYBgbCIdgGNmjJN9mcT7VZbBYLnKAp8PQsbVbmHxmmXTpY/xj+geUuF3ELIhTjLcjOB4UW0/FNUjtM9taYriGwVUKo9cJ+652QkFs3QBerxMzqPEObG3NS2h99WrtV1LmayBN2m9ncJJ8Kjk2oSdn/P+ua2CpqM4G6f8AFeitfdRdS94js3A/6GEZGY8WFHMrslvfc8YMj72MxPJ1qv3zF15BBzEKrRcoZWdywRyXDGPpTIXrlGFOiGzxS07FdekYj5V6qW7pD0wuqVug3fyU5wt+Jx4Yvk8dG2voywkqxFzRQfbTL/Wv0+54a+AFK2HFZjY9oXXgiVHpqPK0fv+meTSMoVyQTbVXwfZvNGm5sROJlfM5tiV6UKRbBUx+/6+39H2unwnItIFIMANKJPiS9x8B3Vkxuc8ZdpZe8owfrL6otEPzWSXsDK0zKYvvK+Mxmb40cZZKiaLzXmsEiVTQ9JJX9ycE6xFiCQTjd91zy5Os7xaY6vLPLegdWCbbOq4bpIpX0vt0RPHLWvG3vyzX6tPiy77z9AxOohd4hqLpiH1nA2Ua3+AjcYRYjU7NA1PnbFThBulH7O1TMFtShpLdlZAGl4op926iZVRYZjGAdfbkLCrHmoggsB15DjFWbNwEuuZzpuX5tcIZLXqxNdOrECrwXAYM6K1HtBC/wDpqlNfFb7LEaKRhv++KHE3K6UXekLpPR5h22ttIMbMAjZrBdjXVA9fagPtB1gmY0fH4j0b8Wd6j6Fj8MjjhirvTmRAZHV0Zq1dqw8QDFELOVE1bczZJ2vUDgGoL5cCNgAsjOCejJCsSe2MWiWQgvM8zmwv2eSKHSsVuQ6E4urovXmVdoEdDdar10juldAVVQ5FfSbtZrNpVmK2EHx2s7rBKySR+KWpf1DXNQWa9YmSzxQH4RrVaUB5OSwqhDyxOH4i9HeNzHsK56y/6tumToKA/QCUp2CqZp++OrLNkgy7n3bx1NN3Qm8uIIWQVT5HKJoI0CmvzuSrHAxQQVTkcZ5dMsUF/RQy0lN8ztuF0yTEqRWl4efUoX8RViGJkTyGkQngjZX4XnH7S4mAuvHFBTGFzFmSGUfxeWO9lIXhPUN1yslWxQBxCmGIp7YGmB9k+8WF8z1OgRaYbCbql7DveTcegNyoZXzfpjF3YJ4AQXuvSlKIwK7qsLEKBwmawxwt2yT0SjWuO41AgpeLH9s2JRLPZ+ZY+1RWPG8a4lfl+fMchIQH8qmULGgaqlzbq7VZmRnmeyYOz75v1mvSqNFijCrnlzB4QZcSNI05ylTtvRE6C/WezeY3dc9uVdBRWp1i8jzm6RhFid40C9SCtxrvbv/O3RjfiwsibZp4JWNbIPBmt08aUn0nMjpoaXcQXPTIDLtiYCziECD0Mlf5mz2DaK0ecltI5CfsFT/Yi0zmrbmOARiOP3zkYiCP8bVcWu2sOyC1HB5Dlf3ak8ver5lOJIq43dIG0++LwwxGzgIiQx5MPdWCs1dKD6cREKNdtyjcW689N6Q0hwC7Lj4od2W6oYe2cOOfp6IriKlYUP//a1lAnBI6xaHcy50YoJud77Et3nCUWWyZLS75fMaqNqG+cioe1arnk/n9vIpibZqOyKbPJvNcbTAimshZZY8BJgeRTbm/Jjaka79WFXKxq9gwnl+jUjuxpEhMlkoRAezH4EGK/hdGjnfSk5L54ppxxEGMLBlpjbEaUA+9mSj5OcSqz1iSHUvI8v9RHVyXFixRXCvv9EHsJew";
string actualPlain = Utilities.SM4Utility.DecryptWithGCM(key: key, nonce: nonce, aad: aad, cipherText: cipherText);
string actualPlain = Utilities.SM4Utility.DecryptWithGCM(encodingKey: new EncodedString(key, EncodingKinds.Literal), encodingNonce: new EncodedString(nonce, EncodingKinds.Literal), encodingAssociatedData: new EncodedString(aad, EncodingKinds.Literal), encodingCipher: new EncodedString(cipherText, EncodingKinds.Base64))!;
string expectedPlain = "-----BEGIN CERTIFICATE-----MIID3DCCAsSgAwIBAgIUGZNrTcamx3sFSJsQli3v9C6gZe8wDQYJKoZIhvcNAQELBQAwXjELMAkGA1UEBhMCQ04xEzARBgNVBAoTClRlbnBheS5jb20xHTAbBgNVBAsTFFRlbnBheS5jb20gQ0EgQ2VudGVyMRswGQYDVQQDExJUZW5wYXkuY29tIFJvb3QgQ0EwHhcNMjAwODAxMDczNTE4WhcNMjUwNzMxMDczNTE4WjBuMRgwFgYDVQQDDA9UZW5wYXkuY29tIHNpZ24xEzARBgNVBAoMClRlbnBheS5jb20xHTAbBgNVBAsMFFRlbnBheS5jb20gQ0EgQ2VudGVyMQswCQYDVQQGDAJDTjERMA8GA1UEBwwIU2hlblpoZW4wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDOAYHqxCqaRzoTIvgVixaYJJvmvHbiczbx5MQ9XL1ITSFxkTsNsk7RKHnO7eBS5imheJgQwd22Ky+XclSe7B4odssu/l/+gHo2gooTYrrCpQrOkpvGMf8R8aI56BQIF+vsomDvVq1NojHV2FqljMwFXzhj2EmU6p6gDv9iL7q1NrfnxFx8iJe4OhIB5Ek4qn1xXxrTUhiULd2vXlbIXhRetZSNcJsLt5Rw7D7c8F+aX2JchfeqsZECwKW7bSjMbVWWC6M9MgkB/aId8P0y7qEiiXFJkfkg1I/E1ud2apopsid5tdCyRRR6+MhhX2EC8S04MN4soUT7haqNNxX2rKHnAgMBAAGjgYEwfzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DBlBgNVHR8EXjBcMFqgWKBWhlRodHRwOi8vZXZjYS5pdHJ1cy5jb20uY24vcHVibGljL2l0cnVzY3JsP0NBPTFCRDQyMjBFNTBEQkMwNEIwNkFEMzk3NTQ5ODQ2QzAxQzNFOEVCRDIwDQYJKoZIhvcNAQELBQADggEBAJyg2z4oLQmPfftLQWyzbUc9ONhRMtfA+tVlVBgtLLKnWuDlsmEntheM07fu84F4pcfs3yHzjD7pAOFbO4Yt1yhQ50DK35sjbRWepPdWJZLlni7KBctcmm0o4zq37oB7vonmBEbFqYs9DaINYOjgI3J25iSBkPVC7dBbvFj2xB0LcIcXipq30tDdC/oUem27MNzwZAt49WthKhw6u3HSkcE5cO4LyYTsJhSyG/7LXwvVMgX4Jyzo0SSiGOU1/beaZssTVI8sTPJVlHWjhNE3Lc2SaAlKGfGwvt0X3cEZEF+7oEZIFTkkAF2JhqfnpR3gST0G8Umq1SaVtCPP/zVI8x0=-----END CERTIFICATE-----";
Assert.Equal(expectedPlain, actualPlain);