feat(core): 抽离公共的算法工具类

This commit is contained in:
Fu Diwei
2021-06-07 00:28:00 +08:00
parent 9887745358
commit f887778282
15 changed files with 141 additions and 61 deletions

View File

@@ -56,10 +56,10 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
plainJson = Utilities.AesUtil.DecryptWithGCM(
aesKey: client.MerchantV3Secret,
nonce: resource.Nonce,
associatedData: resource.AssociatedData,
plainJson = Utilities.AESUtility.DecryptWithGCM(
key: client.MerchantV3Secret,
iv: resource.Nonce,
aad: resource.AssociatedData,
cipherText: resource.CipherText
);
}

View File

@@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (string.IsNullOrEmpty(request.FileHash))
request.FileHash = Utilities.Sha256Util.Hash(request.FileBytes).ToLower();
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
if (string.IsNullOrEmpty(request.FileContentType))
{

View File

@@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (string.IsNullOrEmpty(request.FileHash))
request.FileHash = Utilities.Sha256Util.Hash(request.FileBytes).ToLower();
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
if (string.IsNullOrEmpty(request.FileContentType))
{
@@ -81,7 +81,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".mp4";
if (string.IsNullOrEmpty(request.FileHash))
request.FileHash = Utilities.Sha256Util.Hash(request.FileBytes).ToLower();
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
if (string.IsNullOrEmpty(request.FileContentType))
{

View File

@@ -244,7 +244,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png";
if (string.IsNullOrEmpty(request.FileHash))
request.FileHash = Utilities.Sha256Util.Hash(request.FileBytes).ToLower();
request.FileHash = Security.SHA256Utility.Hash(request.FileBytes).ToLower();
if (string.IsNullOrEmpty(request.FileContentType))
{

View File

@@ -42,7 +42,7 @@ 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.RsaUtil.SignWithSHA256(
string sign = Utilities.RSAUtility.SignWithSHA256(
privateKey: client.MerchantCertPrivateKey,
plainText: $"{appId}\n{timestamp}\n{nonce}\n{package}"
);
@@ -97,7 +97,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
string timestamp = DateTimeOffset.Now.ToLocalTime().ToUnixTimeSeconds().ToString();
string nonce = Guid.NewGuid().ToString("N");
string sign = Utilities.RsaUtil.SignWithSHA256(
string sign = Utilities.RSAUtility.SignWithSHA256(
privateKey: client.MerchantCertPrivateKey,
plainText: $"{appId}\n{timestamp}\n{nonce}\n{prepayId}"
);

View File

@@ -38,7 +38,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
accountValidationModel.AccountNameEncryptedData = Utilities.RsaUtil.DecryptWithECB(
accountValidationModel.AccountNameEncryptedData = Utilities.RSAUtility.DecryptWithECB(
client.MerchantCertPrivateKey,
accountValidationModel.AccountNameEncryptedData
);
@@ -53,7 +53,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
accountValidationModel.AccountNumberEncryptedData = Utilities.RsaUtil.DecryptWithECB(
accountValidationModel.AccountNumberEncryptedData = Utilities.RSAUtility.DecryptWithECB(
client.MerchantCertPrivateKey,
accountValidationModel.AccountNumberEncryptedData!
);
@@ -100,7 +100,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
downloadBillModel.EncryptKeyEncryptedData = Utilities.RsaUtil.DecryptWithECB(
downloadBillModel.EncryptKeyEncryptedData = Utilities.RSAUtility.DecryptWithECB(
client.MerchantCertPrivateKey,
downloadBillModel.EncryptKeyEncryptedData
);
@@ -144,7 +144,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
response.PayerPhoneEncryptedData = Utilities.RsaUtil.DecryptWithECB(
response.PayerPhoneEncryptedData = Utilities.RSAUtility.DecryptWithECB(
client.MerchantCertPrivateKey,
response.PayerPhoneEncryptedData!
);
@@ -188,10 +188,10 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
certificateModel.EncryptCertificate.CipherText = Utilities.AesUtil.DecryptWithGCM(
aesKey: client.MerchantV3Secret,
nonce: certificateModel.EncryptCertificate.Nonce,
associatedData: certificateModel.EncryptCertificate.AssociatedData,
certificateModel.EncryptCertificate.CipherText = Utilities.AESUtility.DecryptWithGCM(
key: client.MerchantV3Secret,
iv: certificateModel.EncryptCertificate.Nonce,
aad: certificateModel.EncryptCertificate.AssociatedData,
cipherText: certificateModel.EncryptCertificate.CipherText
);
}
@@ -242,7 +242,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
complaintModel.PayerPhoneEncryptedData = Utilities.RsaUtil.DecryptWithECB(
complaintModel.PayerPhoneEncryptedData = Utilities.RSAUtility.DecryptWithECB(
client.MerchantCertPrivateKey,
complaintModel.PayerPhoneEncryptedData!
);
@@ -290,7 +290,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
guideModel.UserNameEncryptedData = Utilities.RsaUtil.DecryptWithECB(
guideModel.UserNameEncryptedData = Utilities.RSAUtility.DecryptWithECB(
client.MerchantCertPrivateKey,
guideModel.UserNameEncryptedData
);
@@ -305,7 +305,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
{
try
{
guideModel.UserMobileEncryptedData = Utilities.RsaUtil.DecryptWithECB(
guideModel.UserMobileEncryptedData = Utilities.RSAUtility.DecryptWithECB(
client.MerchantCertPrivateKey,
guideModel.UserMobileEncryptedData
);

View File

@@ -27,7 +27,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
try
{
return Utilities.RsaUtil.VerifyWithSHA256(
return Utilities.RSAUtility.VerifyWithSHA256(
publicKey: publicKey,
plainText: GetPlainTextForSignature(response),
signature: response.WechatpaySignature
@@ -58,7 +58,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3
try
{
return Utilities.RsaUtil.VerifyWithSHA256ByCertificate(
return Utilities.RSAUtility.VerifyWithSHA256ByCertificate(
certificate: certificate,
plainText: GetPlainTextForSignature(response),
signature: response.WechatpaySignature

View File

@@ -54,7 +54,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Interceptors
{
try
{
signText = Utilities.RsaUtil.SignWithSHA256(_mchCertPk, plainText);
signText = Utilities.RSAUtility.SignWithSHA256(_mchCertPk, plainText);
}
catch (Exception ex)
{

View File

@@ -9,32 +9,32 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// AES 算法工具类。
/// </summary>
public static class AesUtil
public static class AESUtility
{
private const int AES_TAG_LENGH_BIT = 128;
private const int AES_BLOCK_SIZE = 128;
private const string AES_GCM_CIPHER_ALG = "AES/GCM/NoPadding";
/// <summary>
/// 基于 GCM 模式解密数据。
/// </summary>
/// <param name="aesKeyBytes">AES 密钥字节数组。</param>
/// <param name="associatedDataBytes">附加数据包字节数组。</param>
/// <param name="nonceBytes">加密使用的随机串初始化向量字节数组。</param>
/// <param name="keyBytes">AES 密钥字节数组。</param>
/// <param name="ivBytes">加密使用的初始化向量字节数组。</param>
/// <param name="aadBytes">加密使用的附加数据包字节数组。</param>
/// <param name="cipherBytes">待解密数据字节数组。</param>
/// <returns>解密后的数据字节数组。</returns>
public static byte[] DecryptWithGCM(byte[] aesKeyBytes, byte[] nonceBytes, byte[] associatedDataBytes, byte[] cipherBytes)
public static byte[] DecryptWithGCM(byte[] keyBytes, byte[] ivBytes, byte[] aadBytes, byte[] cipherBytes)
{
if (aesKeyBytes == null) throw new ArgumentNullException(nameof(aesKeyBytes));
if (nonceBytes == null) throw new ArgumentNullException(nameof(nonceBytes));
if (associatedDataBytes == null) throw new ArgumentNullException(nameof(associatedDataBytes));
if (keyBytes == null) throw new ArgumentNullException(nameof(keyBytes));
if (ivBytes == null) throw new ArgumentNullException(nameof(ivBytes));
if (aadBytes == null) throw new ArgumentNullException(nameof(aadBytes));
if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes));
IBufferedCipher cipher = CipherUtilities.GetCipher(AES_GCM_CIPHER_ALG);
ICipherParameters aeadParams = new AeadParameters(
new KeyParameter(aesKeyBytes),
AES_TAG_LENGH_BIT,
nonceBytes,
associatedDataBytes
new KeyParameter(keyBytes),
AES_BLOCK_SIZE,
ivBytes,
aadBytes
);
cipher.Init(false, aeadParams);
byte[] plainBytes = new byte[cipher.GetOutputSize(cipherBytes.Length)];
@@ -46,21 +46,21 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 基于 GCM 模式解密数据。
/// </summary>
/// <param name="aesKey">AES 密钥。</param>
/// <param name="nonce">加密使用的随机串初始化向量。</param>
/// <param name="associatedData">附加数据包。</param>
/// <param name="key">AES 密钥。</param>
/// <param name="iv">加密使用的初始化向量。</param>
/// <param name="aad">加密使用的附加数据包。</param>
/// <param name="cipherText">经 Base64 编码后的待解密数据。</param>
/// <returns>解密后的文本数据。</returns>
public static string DecryptWithGCM(string aesKey, string nonce, string? associatedData, string cipherText)
public static string DecryptWithGCM(string key, string iv, string? aad, string cipherText)
{
if (aesKey == null) throw new ArgumentNullException(nameof(aesKey));
if (nonce == null) throw new ArgumentNullException(nameof(nonce));
if (key == null) throw new ArgumentNullException(nameof(key));
if (iv == null) throw new ArgumentNullException(nameof(iv));
if (cipherText == null) throw new ArgumentNullException(nameof(cipherText));
byte[] plainBytes = DecryptWithGCM(
aesKeyBytes: Encoding.UTF8.GetBytes(aesKey),
nonceBytes: Encoding.UTF8.GetBytes(nonce),
associatedDataBytes: Encoding.UTF8.GetBytes(associatedData ?? string.Empty),
keyBytes: Encoding.UTF8.GetBytes(key),
ivBytes: Encoding.UTF8.GetBytes(iv),
aadBytes: Encoding.UTF8.GetBytes(aad ?? string.Empty),
cipherBytes: Convert.FromBase64String(cipherText)
);
return Encoding.UTF8.GetString(plainBytes);

View File

@@ -13,7 +13,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// RSA 算法工具类。
/// </summary>
public static class RsaUtil
public static class RSAUtility
{
// REF: https://github.com/bcgit/bc-csharp/blob/master/crypto/src/security/CipherUtilities.cs
private const string RSA_CIPHER_ALG = "RSA/ECB/PKCS1";
@@ -91,7 +91,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
/// <summary>
/// 使用证书基于 SHA-256 算法验证签名。
/// </summary>
/// <param name="publicKey">证书cer 格式)。</param>
/// <param name="certificate">证书cer 格式)。</param>
/// <param name="plainText">待验证的文本数据。</param>
/// <param name="signature">经 Base64 编码的待验证的签名。</param>
/// <returns>验证结果。</returns>

View File

@@ -1,42 +0,0 @@
using System;
using System.Text;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Digests;
namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
{
/// <summary>
/// SHA-256 算法工具类。
/// </summary>
public static class Sha256Util
{
/// <summary>
/// 获取信息摘要。
/// </summary>
/// <param name="bytes">信息字节数组。</param>
/// <returns>信息摘要。</returns>
public static string Hash(byte[] bytes)
{
if (bytes == null) throw new ArgumentNullException(nameof(bytes));
IDigest digest = new Sha256Digest();
byte[] hashBytes = new byte[digest.GetDigestSize()];
digest.BlockUpdate(bytes, 0, bytes.Length);
digest.DoFinal(hashBytes, 0);
return BitConverter.ToString(hashBytes).Replace("-", "");
}
/// <summary>
/// 获取信息摘要。
/// </summary>
/// <param name="message">文本信息。</param>
/// <returns>信息摘要。</returns>
public static string Hash(string message)
{
if (message == null) throw new ArgumentNullException(nameof(message));
byte[] bytes = Encoding.UTF8.GetBytes(message);
return Hash(bytes);
}
}
}