style: clean code

This commit is contained in:
Fu Diwei 2022-11-09 20:48:03 +08:00
parent 8efadd6c0b
commit e995d5c523
33 changed files with 232 additions and 234 deletions

View File

@ -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<byte>())).Replace("-", "");
request.FileHash = BitConverter.ToString(Utilities.MD5Utility.Hash(request.FileBytes ?? Array.Empty<byte>())).Replace("-", string.Empty);
}
string boundary = "--BOUNDARY--" + DateTimeOffset.Now.Ticks.ToString("x");

View File

@ -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))

View File

@ -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))

View File

@ -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
}
}
/// <summary>
/// 基于 CBC 模式解密数据。
/// </summary>
/// <param name="encodingKey">经 Base64 编码后的 AES 密钥。</param>
/// <param name="encodingIV">经 Base64 编码后的 AES 初始化向量。</param>
/// <param name="encodingCipherText">经 Base64 编码后的待解密数据。</param>
/// <returns>解密后的文本数据。</returns>
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);
}
/// <summary>
/// 基于 CBC 模式加密数据。
/// </summary>
@ -59,26 +79,6 @@ namespace SKIT.FlurlHttpClient.Wechat.Api.Utilities
}
}
/// <summary>
/// 基于 CBC 模式解密数据。
/// </summary>
/// <param name="encodingKey">经 Base64 编码后的 AES 密钥。</param>
/// <param name="encodingIV">经 Base64 编码后的 AES 初始化向量。</param>
/// <param name="encodingCipherText">经 Base64 编码后的待解密数据。</param>
/// <returns>解密后的文本数据。</returns>
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);
}
/// <summary>
/// 基于 CBC 模式加密数据。
/// </summary>

View File

@ -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);
}
}
}

View File

@ -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<byte>();
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);

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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";

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

View File

@ -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<byte>();
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");

View File

@ -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);
}

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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
/// </summary>
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";
/// <summary>
/// 基于 CBC 模式解密数据。
/// </summary>
/// <param name="keyBytes">密钥字节数据。</param>
/// <param name="ivBytes">偏移量字节数据。</param>
/// <param name="cipherBytes">待解密的数据字节数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="SM4_CIPHER_PADDING_PKCS7PADDING"/></param>
/// <returns>解密后的数据字节数组。</returns>
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);
}
/// <summary>
/// 基于 CBC 模式解密数据。
/// </summary>
/// <param name="key">经 Base64 编码的密钥。</param>
/// <param name="iv">>经 Base64 编码的偏移量。</param>
/// <param name="cipherText">经 Base64 编码的待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="SM4_CIPHER_PADDING_PKCS7PADDING"/></param>
/// <returns>解密后的文本数据。</returns>
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);
}
/// <summary>
@ -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)
/// <summary>
/// 基于 CBC 模式解密数据。
/// </summary>
/// <param name="keyBytes">密钥字节数据。</param>
/// <param name="ivBytes">偏移量字节数据。</param>
/// <param name="cipherBytes">待解密的数据字节数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="SM4_CIPHER_PADDING_PKCS7PADDING"/></param>
/// <returns>解密后的数据字节数组。</returns>
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)
/// <summary>
/// 基于 CBC 模式解密数据。
/// </summary>
/// <param name="key">经 Base64 编码的密钥。</param>
/// <param name="iv">>经 Base64 编码的偏移量。</param>
/// <param name="cipherText">经 Base64 编码的待解密数据。</param>
/// <param name="paddingMode">填充模式。(默认值:<see cref="SM4_CIPHER_PADDING_PKCS7PADDING"/></param>
/// <returns>解密后的文本数据。</returns>
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);
}
}
}

View File

@ -159,7 +159,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
{
TResponse result = await base.WrapResponseWithJsonAsync<TResponse>(flurlResponse, cancellationToken);
string? strTBEPEncryption = flurlResponse.Headers.GetAll("TBEP-Encrypt").FirstOrDefault();
string? strTBEPEncryption = flurlResponse.Headers.FirstOrDefault("TBEP-Encrypt");
if (!string.IsNullOrEmpty(strTBEPEncryption))
{
IDictionary<string, string?> dictTBEPEncryption = strTBEPEncryption

View File

@ -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<byte>())).Replace("-", "").ToLower();
request.FileHash = BitConverter.ToString(Utilities.MD5Utility.Hash(request.FileBytes ?? Array.Empty<byte>())).Replace("-", string.Empty).ToLower();
IFlurlRequest flurlReq = client
.CreateRequest(request, HttpMethod.Post, "secapi", "mch", "uploadmedia");

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Security.Cryptography;
using System.Text;

View File

@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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<byte>())).Replace("-", "").ToLower();
request.FileHash = BitConverter.ToString(Utilities.SHA256Utility.Hash(request.FileBytes ?? Array.Empty<byte>())).Replace("-", string.Empty).ToLower();
if (request.FileContentType == null)
request.FileContentType = Utilities.FileNameToContentTypeMapper.GetContentTypeForImage(request.FileName!) ?? "text/plain";

View File

@ -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";

View File

@ -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";

View File

@ -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";

View File

@ -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
/// </summary>
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";
/// <summary>
/// 基于 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
);

View File

@ -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<byte>();
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");

View File

@ -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);
}
/// <summary>
/// 使用私钥基于 SHA-256 算法生成签名。
/// </summary>
@ -108,40 +171,6 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
return VerifyWithSHA256(rsaKeyParams, plainBytes, signBytes);
}
/// <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>
/// <returns>解密后的数据字节数组。</returns>
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);
}
/// <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)
{
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);
}
/// <summary>
/// 使用公钥基于 ECB 模式加密数据。
/// </summary>
@ -194,6 +223,40 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
return Convert.ToBase64String(cipherBytes);
}
/// <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>
/// <returns>解密后的数据字节数组。</returns>
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);
}
/// <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)
{
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);
}
/// <summary>
/// <para>从 CRT/CER 证书中导出 PKCS#8 公钥。</para>
/// <para>
@ -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);
}
}
}

View File

@ -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);
}
}
}

View File

@ -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))

View File

@ -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))

View File

@ -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<byte>();
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);

View File

@ -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);
}
}
}

View File

@ -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));
}
}