From e995d5c523ab88ab5314c01249808c2db3fe6f17 Mon Sep 17 00:00:00 2001 From: Fu Diwei Date: Wed, 9 Nov 2022 20:48:03 +0800 Subject: [PATCH] style: clean code --- .../WechatAdsClientExecuteImagesExtensions.cs | 4 +- ...piClientExecuteCgibinMaterialExtensions.cs | 4 +- ...atApiClientExecuteCgibinMediaExtensions.cs | 4 +- .../Utilities/AESUtility.cs | 42 ++-- .../Utilities/HMACUtility.cs | 4 +- .../Internal/FileHttpContentBuilder.cs | 6 +- .../Utilities/SHA1Utility.cs | 4 +- .../Utilities/SHA1Utility.cs | 4 +- ...inessClientExecuteFileUploadsExtensions.cs | 4 +- ...npayBusinessRequestSignatureInterceptor.cs | 2 +- .../Internal/FileHttpContentBuilder.cs | 4 +- .../Utilities/RSAUtility.cs | 14 +- .../Utilities/SHA256Utility.cs | 4 +- .../Utilities/SM3Utility.cs | 4 +- .../Utilities/SM4Utility.cs | 87 ++++---- .../WechatTenpayBusinessClient.cs | 2 +- ...payClientExecuteMerchantMediaExtensions.cs | 4 +- .../Utilities/AESUtility.cs | 2 +- .../Utilities/HMACUtility.cs | 4 +- .../Utilities/MD5Utility.cs | 4 +- ...payClientExecuteMarketingBankExtensions.cs | 2 +- ...ayClientExecuteMarketingMediaExtensions.cs | 4 +- ...payClientExecuteMerchantMediaExtensions.cs | 6 +- ...yClientExecuteMerchantServiceExtensions.cs | 4 +- .../Utilities/AESUtility.cs | 11 +- .../Internal/FileHttpContentBuilder.cs | 4 +- .../Utilities/RSAUtility.cs | 196 +++++++++--------- .../Utilities/SHA256Utility.cs | 4 +- ...tWorkClientExecuteCgibinMediaExtensions.cs | 6 +- ...orkClientExecuteCgibinServiceExtensions.cs | 4 +- .../Internal/FileHttpContentBuilder.cs | 6 +- .../Utilities/SHA1Utility.cs | 4 +- .../TestClients.cs | 8 +- 33 files changed, 232 insertions(+), 234 deletions(-) diff --git a/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs index 2dbe9942..c2d23645 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Ads/Extensions/WechatAdsClientExecuteImagesExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; @@ -35,7 +35,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Ads if (request.FileHash == null) { - request.FileHash = BitConverter.ToString(Utilities.MD5Utility.Hash(request.FileBytes ?? Array.Empty())).Replace("-", ""); + request.FileHash = BitConverter.ToString(Utilities.MD5Utility.Hash(request.FileBytes ?? Array.Empty())).Replace("-", string.Empty); } string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x"); diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs index c67a6d0d..c1ec8b9d 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMaterialExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Text; using System.Threading; @@ -52,7 +52,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api if (request.FileName == null) { - string ext = ""; + string ext = string.Empty; if (TYPE_IMAGE.Equals(request.Type)) ext = ".png"; else if (TYPE_THUMB.Equals(request.Type)) diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs index c7fcc2cd..8481fe82 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Extensions/WechatApiClientExecuteCgibinMediaExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; @@ -31,7 +31,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api if (request.FileName == null) { - string ext = ""; + string ext = string.Empty; if (TYPE_IMAGE.Equals(request.Type)) ext = ".png"; else if (TYPE_THUMB.Equals(request.Type)) diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/AESUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/AESUtility.cs index c1ef2abd..d6dfe0fb 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/AESUtility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/AESUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -34,6 +34,26 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities } } + /// + /// 基于 CBC 模式解密数据。 + /// + /// 经 Base64 编码后的 AES 密钥。 + /// 经 Base64 编码后的 AES 初始化向量。 + /// 经 Base64 编码后的待解密数据。 + /// 解密后的文本数据。 + public static string DecryptWithCBC(string encodingKey, string encodingIV, string encodingCipherText) + { + if (encodingKey == null) throw new ArgumentNullException(nameof(encodingKey)); + if (encodingCipherText == null) throw new ArgumentNullException(nameof(encodingCipherText)); + + byte[] plainBytes = DecryptWithCBC( + keyBytes: Convert.FromBase64String(encodingKey), + ivBytes: Convert.FromBase64String(encodingIV), + cipherBytes: Convert.FromBase64String(encodingCipherText) + ); + return Encoding.UTF8.GetString(plainBytes); + } + /// /// 基于 CBC 模式加密数据。 /// @@ -59,26 +79,6 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities } } - /// - /// 基于 CBC 模式解密数据。 - /// - /// 经 Base64 编码后的 AES 密钥。 - /// 经 Base64 编码后的 AES 初始化向量。 - /// 经 Base64 编码后的待解密数据。 - /// 解密后的文本数据。 - public static string DecryptWithCBC(string encodingKey, string encodingIV, string encodingCipherText) - { - if (encodingKey == null) throw new ArgumentNullException(nameof(encodingKey)); - if (encodingCipherText == null) throw new ArgumentNullException(nameof(encodingCipherText)); - - byte[] plainBytes = DecryptWithCBC( - keyBytes: Convert.FromBase64String(encodingKey), - ivBytes: Convert.FromBase64String(encodingIV), - cipherBytes: Convert.FromBase64String(encodingCipherText) - ); - return Encoding.UTF8.GetString(plainBytes); - } - /// /// 基于 CBC 模式加密数据。 /// diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/HMACUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/HMACUtility.cs index cc5bf3d8..8aa68cb1 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/HMACUtility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/HMACUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -38,7 +38,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities byte[] secretBytes = Encoding.UTF8.GetBytes(secret); byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = HashWithSHA256(secretBytes, msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/Internal/FileHttpContentBuilder.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/Internal/FileHttpContentBuilder.cs index 3853d482..69cf1dcd 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/Internal/FileHttpContentBuilder.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/Internal/FileHttpContentBuilder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text; @@ -18,10 +18,10 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities if (formDataName == null) throw new ArgumentNullException(nameof(formDataName)); if (configureFileHttpContent == null) throw new ArgumentNullException(nameof(configureFileHttpContent)); - fileName = fileName.Replace("\"", ""); + fileName = fileName.Replace("\"", string.Empty); fileBytes = fileBytes ?? Array.Empty(); fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType; - formDataName = formDataName.Replace("\"", ""); + formDataName = formDataName.Replace("\"", string.Empty); // HACKED: 默认不支持 Unicode 文件名 https://github.com/dotnet/runtime/issues/22996 byte[] bytesFileName = Encoding.UTF8.GetBytes(fileName); diff --git a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/SHA1Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/SHA1Utility.cs index 1d64c088..0e47ea17 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/SHA1Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Api/Utilities/SHA1Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = Hash(msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Utilities/SHA1Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Utilities/SHA1Utility.cs index 3d18f3fc..e5d8dcbf 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Utilities/SHA1Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.OpenAI/Utilities/SHA1Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.OpenAI.Utilities byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = Hash(msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientExecuteFileUploadsExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientExecuteFileUploadsExtensions.cs index 961d3a1d..0e9d34e5 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientExecuteFileUploadsExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientExecuteFileUploadsExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -24,7 +24,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png"; if (request.FileHash == null) - request.FileHash = BitConverter.ToString(Utilities.SM3Utility.Hash(request.FileBytes)).Replace("-", "").ToLower(); + request.FileHash = BitConverter.ToString(Utilities.SM3Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower(); if (request.FileContentType == null) request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png"; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Interceptors/WechatTenpayBusinessRequestSignatureInterceptor.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Interceptors/WechatTenpayBusinessRequestSignatureInterceptor.cs index d8e03e93..44b8836a 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Interceptors/WechatTenpayBusinessRequestSignatureInterceptor.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Interceptors/WechatTenpayBusinessRequestSignatureInterceptor.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Net.Http; using System.Threading.Tasks; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/Internal/FileHttpContentBuilder.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/Internal/FileHttpContentBuilder.cs index ced4e28c..0be298e7 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/Internal/FileHttpContentBuilder.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/Internal/FileHttpContentBuilder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text; @@ -22,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities fileBytes = fileBytes ?? Array.Empty(); fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType; - formDataName = formDataName.Replace("\"", ""); + formDataName = formDataName.Replace("\"", string.Empty); ByteArrayContent metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(fileMetaJson)); metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs index 81854341..2ffcd86f 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using System.Text.RegularExpressions; using Org.BouncyCastle.Crypto; @@ -155,18 +155,18 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities private static byte[] ConvertPkcs8PrivateKeyToByteArray(string privateKey) { privateKey = privateKey - .Replace("-----BEGIN PRIVATE KEY-----", "") - .Replace("-----END PRIVATE KEY-----", ""); - privateKey = Regex.Replace(privateKey, "\\s+", ""); + .Replace("-----BEGIN PRIVATE KEY-----", string.Empty) + .Replace("-----END PRIVATE KEY-----", string.Empty); + privateKey = Regex.Replace(privateKey, "\\s+", string.Empty); return Convert.FromBase64String(privateKey); } private static byte[] ConvertPkcs8PublicKeyToByteArray(string publicKey) { publicKey = publicKey - .Replace("-----BEGIN PUBLIC KEY-----", "") - .Replace("-----END PUBLIC KEY-----", ""); - publicKey = Regex.Replace(publicKey, "\\s+", ""); + .Replace("-----BEGIN PUBLIC KEY-----", string.Empty) + .Replace("-----END PUBLIC KEY-----", string.Empty); + publicKey = Regex.Replace(publicKey, "\\s+", string.Empty); return Convert.FromBase64String(publicKey); } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SHA256Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SHA256Utility.cs index 414d05b8..d8a9bb29 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SHA256Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SHA256Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = Hash(msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs index 2f52479e..c09b7ed4 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Org.BouncyCastle.Crypto; @@ -364,7 +364,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = Hash(msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM4Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM4Utility.cs index 75348f74..67cc0f61 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM4Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM4Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; @@ -11,47 +11,22 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities /// public static class SM4Utility { - // REF: https://github.com/bcgit/bc-csharp/blob/master/crypto/src/security/CipherUtilities.cs - private const string SM4_ALG_NAME = "SM4"; + private const string SM4_ALGORITHM_NAME = "SM4"; private const string SM4_CIPHER_ALGORITHM_CBC = "SM4/CBC"; private const string SM4_CIPHER_PADDING_PKCS7PADDING = "PKCS7PADDING"; - /// - /// 基于 CBC 模式解密数据。 - /// - /// 密钥字节数据。 - /// 偏移量字节数据。 - /// 待解密的数据字节数据。 - /// 填充模式。(默认值:) - /// 解密后的数据字节数组。 - public static byte[] DecryptWithCBC(byte[] keyBytes, byte[] ivBytes, byte[] cipherBytes, string paddingMode = SM4_CIPHER_PADDING_PKCS7PADDING) + private static byte[] DecryptWithCBC(ICipherParameters sm4KeyParams, byte[] cipherBytes, string paddingMode) { - if (keyBytes == null) throw new ArgumentNullException(nameof(keyBytes)); - if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes)); - - KeyParameter sm4KeyParams = ParameterUtilities.CreateKeyParameter(SM4_ALG_NAME, keyBytes); - ParametersWithIV sm4keyParamsWithIv = new ParametersWithIV(sm4KeyParams, ivBytes); - return DecryptWithCBC(sm4keyParamsWithIv, cipherBytes, paddingMode); + IBufferedCipher cipher = CipherUtilities.GetCipher($"{SM4_CIPHER_ALGORITHM_CBC}/{paddingMode}"); + cipher.Init(false, sm4KeyParams); + return cipher.DoFinal(cipherBytes); } - /// - /// 基于 CBC 模式解密数据。 - /// - /// 经 Base64 编码的密钥。 - /// >经 Base64 编码的偏移量。 - /// 经 Base64 编码的待解密数据。 - /// 填充模式。(默认值:) - /// 解密后的文本数据。 - public static string DecryptWithCBC(string key, string iv, string cipherText, string paddingMode = SM4_CIPHER_PADDING_PKCS7PADDING) + private static byte[] EncryptWithCBC(ICipherParameters sm4KeyParams, byte[] plainBytes, string paddingMode) { - if (key == null) throw new ArgumentNullException(nameof(key)); - if (cipherText == null) throw new ArgumentNullException(nameof(cipherText)); - - byte[] keyBytes = Convert.FromBase64String(key); - byte[] ivBytes = Convert.FromBase64String(iv); - byte[] cipherBytes = Convert.FromBase64String(cipherText); - byte[] plainBytes = DecryptWithCBC(keyBytes, ivBytes, cipherBytes, paddingMode); - return Encoding.UTF8.GetString(plainBytes); + IBufferedCipher cipher = CipherUtilities.GetCipher($"{SM4_CIPHER_ALGORITHM_CBC}/{paddingMode}"); + cipher.Init(true, sm4KeyParams); + return cipher.DoFinal(plainBytes); } /// @@ -67,7 +42,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities if (keyBytes == null) throw new ArgumentNullException(nameof(keyBytes)); if (plainBytes == null) throw new ArgumentNullException(nameof(plainBytes)); - KeyParameter sm4KeyParams = ParameterUtilities.CreateKeyParameter(SM4_ALG_NAME, keyBytes); + KeyParameter sm4KeyParams = ParameterUtilities.CreateKeyParameter(SM4_ALGORITHM_NAME, keyBytes); ParametersWithIV sm4keyParamsWithIv = new ParametersWithIV(sm4KeyParams, ivBytes); return EncryptWithCBC(sm4keyParamsWithIv, plainBytes, paddingMode); } @@ -92,18 +67,42 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities return Convert.ToBase64String(cipherBytes); } - private static byte[] EncryptWithCBC(ICipherParameters sm4KeyParams, byte[] plainBytes, string paddingMode) + /// + /// 基于 CBC 模式解密数据。 + /// + /// 密钥字节数据。 + /// 偏移量字节数据。 + /// 待解密的数据字节数据。 + /// 填充模式。(默认值:) + /// 解密后的数据字节数组。 + public static byte[] DecryptWithCBC(byte[] keyBytes, byte[] ivBytes, byte[] cipherBytes, string paddingMode = SM4_CIPHER_PADDING_PKCS7PADDING) { - IBufferedCipher cipher = CipherUtilities.GetCipher($"{SM4_CIPHER_ALGORITHM_CBC}/{paddingMode}"); - cipher.Init(true, sm4KeyParams); - return cipher.DoFinal(plainBytes); + if (keyBytes == null) throw new ArgumentNullException(nameof(keyBytes)); + if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes)); + + KeyParameter sm4KeyParams = ParameterUtilities.CreateKeyParameter(SM4_ALGORITHM_NAME, keyBytes); + ParametersWithIV sm4keyParamsWithIv = new ParametersWithIV(sm4KeyParams, ivBytes); + return DecryptWithCBC(sm4keyParamsWithIv, cipherBytes, paddingMode); } - private static byte[] DecryptWithCBC(ICipherParameters sm4KeyParams, byte[] cipherBytes, string paddingMode) + /// + /// 基于 CBC 模式解密数据。 + /// + /// 经 Base64 编码的密钥。 + /// >经 Base64 编码的偏移量。 + /// 经 Base64 编码的待解密数据。 + /// 填充模式。(默认值:) + /// 解密后的文本数据。 + public static string DecryptWithCBC(string key, string iv, string cipherText, string paddingMode = SM4_CIPHER_PADDING_PKCS7PADDING) { - IBufferedCipher cipher = CipherUtilities.GetCipher($"{SM4_CIPHER_ALGORITHM_CBC}/{paddingMode}"); - cipher.Init(false, sm4KeyParams); - return cipher.DoFinal(cipherBytes); + if (key == null) throw new ArgumentNullException(nameof(key)); + if (cipherText == null) throw new ArgumentNullException(nameof(cipherText)); + + byte[] keyBytes = Convert.FromBase64String(key); + byte[] ivBytes = Convert.FromBase64String(iv); + byte[] cipherBytes = Convert.FromBase64String(cipherText); + byte[] plainBytes = DecryptWithCBC(keyBytes, ivBytes, cipherBytes, paddingMode); + return Encoding.UTF8.GetString(plainBytes); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClient.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClient.cs index 53e5374a..006845d0 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClient.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/WechatTenpayBusinessClient.cs @@ -159,7 +159,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness { TResponse result = await base.WrapResponseWithJsonAsync(flurlResponse, cancellationToken); - string? strTBEPEncryption = flurlResponse.Headers.GetAll("TBEP-Encrypt").FirstOrDefault(); + string? strTBEPEncryption = flurlResponse.Headers.FirstOrDefault("TBEP-Encrypt"); if (!string.IsNullOrEmpty(strTBEPEncryption)) { IDictionary dictTBEPEncryption = strTBEPEncryption diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs index d5ff79c8..1a716177 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Net.Http; using System.Net.Http.Headers; @@ -29,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2 request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".jpg"; if (request.FileHash == null) - request.FileHash = BitConverter.ToString(Utilities.MD5Utility.Hash(request.FileBytes ?? Array.Empty())).Replace("-", "").ToLower(); + request.FileHash = BitConverter.ToString(Utilities.MD5Utility.Hash(request.FileBytes ?? Array.Empty())).Replace("-", string.Empty).ToLower(); IFlurlRequest flurlReq = client .CreateRequest(request, HttpMethod.Post, "secapi", "mch", "uploadmedia"); diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/AESUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/AESUtility.cs index a95abd28..e18e7634 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/AESUtility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/AESUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/HMACUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/HMACUtility.cs index 8cb62fc5..b1427e3e 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/HMACUtility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/HMACUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -38,7 +38,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.Utilities byte[] secretBytes = Encoding.UTF8.GetBytes(secret); byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = HashWithSHA256(secretBytes, msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/MD5Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/MD5Utility.cs index d1cfad43..b89c5db3 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/MD5Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV2/Utilities/MD5Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV2.Utilities byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = Hash(msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs index ea073c18..f0bd431d 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingBankExtensions.cs @@ -29,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".txt"; if (request.FileHash == null) - request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes ?? Array.Empty())).Replace("-", "").ToLower(); + request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes ?? Array.Empty())).Replace("-", string.Empty).ToLower(); if (request.FileContentType == null) request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "text/plain"; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs index 30f47182..c798af43 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMarketingMediaExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -29,7 +29,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png"; if (request.FileHash == null) - request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", "").ToLower(); + request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower(); if (request.FileContentType == null) request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png"; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs index a8827cfd..b69e6b16 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantMediaExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -30,7 +30,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png"; if (request.FileHash == null) - request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", "").ToLower(); + request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower(); if (request.FileContentType == null) request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png"; @@ -60,7 +60,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".mp4"; if (request.FileHash == null) - request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", "").ToLower(); + request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower(); if (request.FileContentType == null) request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForVideo(request.FileName!) ?? "video/mp4"; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs index bce79606..d886b6b9 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Extensions/WechatTenpayClientExecuteMerchantServiceExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -253,7 +253,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3 request.FileName = Guid.NewGuid().ToString("N").ToLower() + ".png"; if (request.FileHash == null) - request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", "").ToLower(); + request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes)).Replace("-", string.Empty).ToLower(); if (request.FileContentType == null) request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "image/png"; diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/AESUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/AESUtility.cs index cf0f446d..d6f73f58 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/AESUtility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/AESUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Text; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Parameters; @@ -11,8 +11,8 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities /// public static class AESUtility { - private const int AES_BLOCK_SIZE = 128; - private const string AES_GCM_CIPHER_ALG = "AES/GCM/NoPadding"; + private const string AES_CIPHER_ALGORITHM_GCM = "AES/GCM"; + private const string AES_CIPHER_PADDING_NOPADDING = "NoPadding"; /// /// 基于 GCM 模式解密数据。 @@ -29,10 +29,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities if (aadBytes == null) throw new ArgumentNullException(nameof(aadBytes)); if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes)); - IBufferedCipher cipher = CipherUtilities.GetCipher(AES_GCM_CIPHER_ALG); + const int TAG_LENGTH_BIT = 128; + IBufferedCipher cipher = CipherUtilities.GetCipher(string.Format("{0}/{1}", AES_CIPHER_ALGORITHM_GCM, AES_CIPHER_PADDING_NOPADDING)); ICipherParameters aeadParams = new AeadParameters( new KeyParameter(keyBytes), - AES_BLOCK_SIZE, + TAG_LENGTH_BIT, ivBytes, aadBytes ); diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/Internal/FileHttpContentBuilder.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/Internal/FileHttpContentBuilder.cs index 446397f4..7552200b 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/Internal/FileHttpContentBuilder.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/Internal/FileHttpContentBuilder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text; @@ -22,7 +22,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities fileBytes = fileBytes ?? Array.Empty(); fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType; - formDataName = formDataName.Replace("\"", ""); + formDataName = formDataName.Replace("\"", string.Empty); ByteArrayContent metaContent = new ByteArrayContent(Encoding.UTF8.GetBytes(fileMetaJson)); metaContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json"); diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/RSAUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/RSAUtility.cs index bc98348f..f0a06a40 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/RSAUtility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/RSAUtility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.IO; using System.Text; using System.Text.RegularExpressions; @@ -21,6 +21,69 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities // REF: https://github.com/bcgit/bc-csharp/blob/master/crypto/src/security/SignerUtilities.cs private const string RSA_SIGNER_ALGORITHM_SHA256 = "SHA-256withRSA"; + private static byte[] ConvertPkcs8PrivateKeyToByteArray(string privateKey) + { + privateKey = privateKey + .Replace("-----BEGIN PRIVATE KEY-----", string.Empty) + .Replace("-----END PRIVATE KEY-----", string.Empty); + privateKey = Regex.Replace(privateKey, "\\s+", string.Empty); + return Convert.FromBase64String(privateKey); + } + + private static byte[] ConvertPkcs8PublicKeyToByteArray(string publicKey) + { + publicKey = publicKey + .Replace("-----BEGIN PUBLIC KEY-----", string.Empty) + .Replace("-----END PUBLIC KEY-----", string.Empty); + publicKey = Regex.Replace(publicKey, "\\s+", string.Empty); + return Convert.FromBase64String(publicKey); + } + + private static X509Certificate ParseX509Certificate(string certificate) + { + using (TextReader sreader = new StringReader(certificate)) + { + PemReader pemReader = new PemReader(sreader); + return (X509Certificate)pemReader.ReadObject(); + } + } + + private static RsaKeyParameters ConvertCertificateToPublicKeyParams(string certificate) + { + X509Certificate cert = ParseX509Certificate(certificate); + return (RsaKeyParameters)cert.GetPublicKey(); + } + + private static byte[] SignWithSHA256(RsaKeyParameters rsaPrivateKeyParams, byte[] plainBytes) + { + ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256); + signer.Init(true, rsaPrivateKeyParams); + signer.BlockUpdate(plainBytes, 0, plainBytes.Length); + return signer.GenerateSignature(); + } + + private static bool VerifyWithSHA256(RsaKeyParameters rsaPublicKeyParams, byte[] plainBytes, byte[] signBytes) + { + ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256); + signer.Init(false, rsaPublicKeyParams); + signer.BlockUpdate(plainBytes, 0, plainBytes.Length); + return signer.VerifySignature(signBytes); + } + + private static byte[] DecryptWithECB(RsaKeyParameters rsaPrivateKeyParams, byte[] cipherBytes, string paddingMode) + { + IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_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}"); + cipher.Init(true, rsaPublicKeyParams); + return cipher.DoFinal(plainBytes); + } + /// /// 使用私钥基于 SHA-256 算法生成签名。 /// @@ -108,40 +171,6 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities return VerifyWithSHA256(rsaKeyParams, plainBytes, signBytes); } - /// - /// 使用私钥基于 ECB 模式解密数据。 - /// - /// PKCS#8 私钥字节数据。 - /// 待解密的数据字节数据。 - /// 填充模式。(默认值:) - /// 解密后的数据字节数组。 - public static byte[] DecryptWithECB(byte[] privateKeyBytes, byte[] cipherBytes, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1) - { - if (privateKeyBytes == null) throw new ArgumentNullException(nameof(privateKeyBytes)); - if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes)); - - RsaKeyParameters rsaKeyParams = (RsaKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes); - return DecryptWithECB(rsaKeyParams, cipherBytes, paddingMode); - } - - /// - /// 使用私钥基于 ECB 模式解密数据。 - /// - /// PKCS#8 私钥(PEM 格式)。 - /// 经 Base64 编码的待解密数据。 - /// 填充模式。(默认值:) - /// 解密后的文本数据。 - public static string DecryptWithECB(string privateKey, string cipherText, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1) - { - if (privateKey == null) throw new ArgumentNullException(nameof(privateKey)); - if (cipherText == null) throw new ArgumentNullException(nameof(cipherText)); - - byte[] privateKeyBytes = ConvertPkcs8PrivateKeyToByteArray(privateKey); - byte[] cipherBytes = Convert.FromBase64String(cipherText); - byte[] plainBytes = DecryptWithECB(privateKeyBytes, cipherBytes, paddingMode); - return Encoding.UTF8.GetString(plainBytes); - } - /// /// 使用公钥基于 ECB 模式加密数据。 /// @@ -194,6 +223,40 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities return Convert.ToBase64String(cipherBytes); } + /// + /// 使用私钥基于 ECB 模式解密数据。 + /// + /// PKCS#8 私钥字节数据。 + /// 待解密的数据字节数据。 + /// 填充模式。(默认值:) + /// 解密后的数据字节数组。 + public static byte[] DecryptWithECB(byte[] privateKeyBytes, byte[] cipherBytes, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1) + { + if (privateKeyBytes == null) throw new ArgumentNullException(nameof(privateKeyBytes)); + if (cipherBytes == null) throw new ArgumentNullException(nameof(cipherBytes)); + + RsaKeyParameters rsaKeyParams = (RsaKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes); + return DecryptWithECB(rsaKeyParams, cipherBytes, paddingMode); + } + + /// + /// 使用私钥基于 ECB 模式解密数据。 + /// + /// PKCS#8 私钥(PEM 格式)。 + /// 经 Base64 编码的待解密数据。 + /// 填充模式。(默认值:) + /// 解密后的文本数据。 + public static string DecryptWithECB(string privateKey, string cipherText, string paddingMode = RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1) + { + if (privateKey == null) throw new ArgumentNullException(nameof(privateKey)); + if (cipherText == null) throw new ArgumentNullException(nameof(cipherText)); + + byte[] privateKeyBytes = ConvertPkcs8PrivateKeyToByteArray(privateKey); + byte[] cipherBytes = Convert.FromBase64String(cipherText); + byte[] plainBytes = DecryptWithECB(privateKeyBytes, cipherBytes, paddingMode); + return Encoding.UTF8.GetString(plainBytes); + } + /// /// 从 CRT/CER 证书中导出 PKCS#8 公钥。 /// @@ -255,68 +318,5 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities X509Certificate cert = ParseX509Certificate(certificate); return new DateTimeOffset(cert.NotAfter); } - - private static byte[] ConvertPkcs8PrivateKeyToByteArray(string privateKey) - { - privateKey = privateKey - .Replace("-----BEGIN PRIVATE KEY-----", "") - .Replace("-----END PRIVATE KEY-----", ""); - privateKey = Regex.Replace(privateKey, "\\s+", ""); - return Convert.FromBase64String(privateKey); - } - - private static byte[] ConvertPkcs8PublicKeyToByteArray(string publicKey) - { - publicKey = publicKey - .Replace("-----BEGIN PUBLIC KEY-----", "") - .Replace("-----END PUBLIC KEY-----", ""); - publicKey = Regex.Replace(publicKey, "\\s+", ""); - return Convert.FromBase64String(publicKey); - } - - private static X509Certificate ParseX509Certificate(string certificate) - { - using (TextReader sreader = new StringReader(certificate)) - { - PemReader pemReader = new PemReader(sreader); - return (X509Certificate)pemReader.ReadObject(); - } - } - - private static RsaKeyParameters ConvertCertificateToPublicKeyParams(string certificate) - { - X509Certificate cert = ParseX509Certificate(certificate); - return (RsaKeyParameters)cert.GetPublicKey(); - } - - private static byte[] SignWithSHA256(RsaKeyParameters rsaKeyParams, byte[] plainBytes) - { - ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256); - signer.Init(true, rsaKeyParams); - signer.BlockUpdate(plainBytes, 0, plainBytes.Length); - return signer.GenerateSignature(); - } - - private static bool VerifyWithSHA256(RsaKeyParameters rsaKeyParams, byte[] plainBytes, byte[] signBytes) - { - ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256); - signer.Init(false, rsaKeyParams); - signer.BlockUpdate(plainBytes, 0, plainBytes.Length); - return signer.VerifySignature(signBytes); - } - - private static byte[] EncryptWithECB(RsaKeyParameters rsaKeyParams, byte[] plainBytes, string paddingMode) - { - IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingMode}"); - cipher.Init(true, rsaKeyParams); - return cipher.DoFinal(plainBytes); - } - - private static byte[] DecryptWithECB(RsaKeyParameters rsaKeyParams, byte[] cipherBytes, string paddingMode) - { - IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingMode}"); - cipher.Init(false, rsaKeyParams); - return cipher.DoFinal(cipherBytes); - } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SHA256Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SHA256Utility.cs index 776fc607..17fe08d3 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SHA256Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SHA256Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = Hash(msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinMediaExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinMediaExtensions.cs index 6d0a5f8c..4b919896 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinMediaExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinMediaExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -30,7 +30,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work if (request.FileName == null) { - string ext = ""; + string ext = string.Empty; if (TYPE_IMAGE.Equals(request.Type)) ext = ".png"; else if (TYPE_VOICE.Equals(request.Type)) @@ -111,7 +111,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work if (request.FileName == null) { - string ext = ""; + string ext = string.Empty; if (TYPE_IMAGE.Equals(request.Type)) ext = ".png"; else if (TYPE_VIDEO.Equals(request.Type)) diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinServiceExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinServiceExtensions.cs index c52cc8d8..80c68d6d 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinServiceExtensions.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinServiceExtensions.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Threading; using System.Threading.Tasks; @@ -286,7 +286,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work if (request.FileName == null) { - string ext = ""; + string ext = string.Empty; if (TYPE_IMAGE.Equals(request.Type)) ext = ".png"; else if (TYPE_VOICE.Equals(request.Type)) diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/Internal/FileHttpContentBuilder.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/Internal/FileHttpContentBuilder.cs index a1c7285b..7266eca2 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/Internal/FileHttpContentBuilder.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/Internal/FileHttpContentBuilder.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Net.Http; using System.Net.Http.Headers; using System.Text; @@ -18,10 +18,10 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities if (formDataName == null) throw new ArgumentNullException(nameof(formDataName)); if (configureFileHttpContent == null) throw new ArgumentNullException(nameof(configureFileHttpContent)); - fileName = fileName.Replace("\"", ""); + fileName = fileName.Replace("\"", string.Empty); fileBytes = fileBytes ?? Array.Empty(); fileContentType = string.IsNullOrEmpty(fileContentType) ? "application/octet-stream" : fileContentType; - formDataName = formDataName.Replace("\"", ""); + formDataName = formDataName.Replace("\"", string.Empty); // HACKED: 默认不支持 Unicode 文件名 https://github.com/dotnet/runtime/issues/22996 byte[] bytesFileName = Encoding.UTF8.GetBytes(fileName); diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/SHA1Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/SHA1Utility.cs index e98c7e7d..a58f7304 100644 --- a/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/SHA1Utility.cs +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Utilities/SHA1Utility.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Security.Cryptography; using System.Text; @@ -33,7 +33,7 @@ namespace SKIT.FlurlHttpClient.Wechat.Work.Utilities byte[] msgBytes = Encoding.UTF8.GetBytes(message); byte[] hashBytes = Hash(msgBytes); - return BitConverter.ToString(hashBytes).Replace("-", ""); + return BitConverter.ToString(hashBytes).Replace("-", string.Empty); } } } diff --git a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/TestClients.cs b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/TestClients.cs index 815a4141..e8520d11 100644 --- a/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/TestClients.cs +++ b/test/SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests/TestClients.cs @@ -1,4 +1,4 @@ -using System.Threading.Tasks; +using System.Threading.Tasks; namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests { @@ -21,11 +21,9 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.UnitTests { var request = new Models.QueryCertificatesRequest(); var response = await Instance.ExecuteQueryCertificatesAsync(request); - - response = Instance.DecryptResponseSensitiveProperty(response); - foreach (var certificateModel in response.CertificateList) + foreach (var certificate in Instance.DecryptResponseSensitiveProperty(response).CertificateList) { - Instance.PlatformCertificateManager.AddEntry(new Settings.CertificateEntry(certificateModel)); + Instance.PlatformCertificateManager.AddEntry(new Settings.CertificateEntry(certificate)); } }