diff --git a/docs/WechatTenpayBusiness/Advanced_EventSignatureVerification.md b/docs/WechatTenpayBusiness/Advanced_EventSignatureVerification.md
index 343c7ef9..445c7dd1 100644
--- a/docs/WechatTenpayBusiness/Advanced_EventSignatureVerification.md
+++ b/docs/WechatTenpayBusiness/Advanced_EventSignatureVerification.md
@@ -22,10 +22,10 @@ bool ret = client.VerifyEventSignature(
由于 `VerifyEventSignature()` 方法内部会 `try-catch` 掉所有异常情况,并直接返回 `false`。为方便开发者在调试阶段排查验签的错误信息,你可以在验证回调通知事件签名时指定接收最后一个 `out` 返回参数,该参数中包含了一些异常的原因和相关堆栈信息。
```csharp
-bool ret = client.VerifyEventSignature(timestamp, nonce, body, signature, serialNumber, out Exception error);
+bool ret = client.VerifyEventSignature(authorization, signature, out Exception error);
if (!ret)
{
Console.WriteLine(error);
- Console.WriteLine(error.InnerException);
+ Console.WriteLine(error?.InnerException);
}
```
diff --git a/docs/WechatTenpayBusiness/Advanced_ResponseSignatureVerification.md b/docs/WechatTenpayBusiness/Advanced_ResponseSignatureVerification.md
index 82c4128a..71aa9507 100644
--- a/docs/WechatTenpayBusiness/Advanced_ResponseSignatureVerification.md
+++ b/docs/WechatTenpayBusiness/Advanced_ResponseSignatureVerification.md
@@ -32,6 +32,6 @@ bool ret = client.VerifyResponseSignature(response, out Exception error);
if (!ret)
{
Console.WriteLine(error);
- Console.WriteLine(error.InnerException);
+ Console.WriteLine(error?.InnerException);
}
```
diff --git a/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md b/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md
index 82a1d32e..137ee057 100644
--- a/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md
+++ b/docs/WechatTenpayV3/Advanced_EventSignatureVerification.md
@@ -58,7 +58,7 @@ bool ret = client.VerifyEventSignature(timestamp, nonce, body, signature, serial
if (!ret)
{
Console.WriteLine(error);
- Console.WriteLine(error.InnerException);
+ Console.WriteLine(error?.InnerException);
}
```
diff --git a/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md b/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md
index 0b1dcb07..8d3e5884 100644
--- a/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md
+++ b/docs/WechatTenpayV3/Advanced_ResponseSignatureVerification.md
@@ -67,7 +67,7 @@ bool ret = client.VerifyResponseSignature(response, out Exception error);
if (!ret)
{
Console.WriteLine(error);
- Console.WriteLine(error.InnerException);
+ Console.WriteLine(error?.InnerException);
}
```
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs
index 6b72b298..32e81c3f 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/Internal/WechatTenpayBusinessClientSignExtensions.cs
@@ -6,12 +6,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
{
internal static class WechatTenpayBusinessClientSignExtensions
{
- public static bool VerifySignature(this WechatTenpayBusinessClient client, string strAuthorization, string strBody)
- {
- return VerifySignature(client, strAuthorization, strBody, out _);
- }
-
- public static bool VerifySignature(this WechatTenpayBusinessClient client, string strAuthorization, string strBody, out Exception? error)
+ public static bool VerifySignature(this WechatTenpayBusinessClient client, string strAuthorization, string strContent, out Exception? error)
{
if (!string.IsNullOrEmpty(strAuthorization))
{
@@ -27,10 +22,17 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
string strTimestamp = dictTBEPAuthorization["timestamp"]!;
string strNonce = dictTBEPAuthorization["nonce"]!;
string strSignature = dictTBEPAuthorization["signature"]!;
- string strSerialNumber = dictTBEPAuthorization["tbep_serial_number"]!;
string strSignAlgorithm = dictTBEPAuthorization["signature_algorithm"]!;
+ string strSerialNumber = dictTBEPAuthorization["tbep_serial_number"]!;
- return VerifySignature(client, strTimestamp, strNonce, strBody, strSignature, strSerialNumber, strSignAlgorithm, out error);
+ return VerifySignature(
+ client,
+ strTimestamp: strTimestamp,
+ strNonce: strNonce,
+ strContent: strContent,
+ strSignature: strSignature,
+ strSignatureAlgorithm: strSignAlgorithm,
+ strSerialNumber: strSerialNumber, out error);
}
catch (Exception ex)
{
@@ -43,26 +45,11 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
return false;
}
- public static bool VerifySignature(this WechatTenpayBusinessClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber)
- {
- return VerifySignature(client, strTimestamp, strNonce, strBody, strSignature, strSerialNumber, Constants.SignAlgorithms.SHA245_WITH_RSA, out _);
- }
-
- public static bool VerifySignature(this WechatTenpayBusinessClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber, string strSignAlgorithm)
- {
- return VerifySignature(client, strTimestamp, strNonce, strBody, strSignature, strSerialNumber, strSignAlgorithm, out _);
- }
-
- public static bool VerifySignature(this WechatTenpayBusinessClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber, out Exception? error)
- {
- return VerifySignature(client, strTimestamp, strNonce, strBody, strSignature, strSerialNumber, Constants.SignAlgorithms.SHA245_WITH_RSA, out error);
- }
-
- public static bool VerifySignature(this WechatTenpayBusinessClient client, string strTimestamp, string strNonce, string strBody, string strSignature, string strSerialNumber, string strSignAlgorithm, out Exception? error)
+ public static bool VerifySignature(this WechatTenpayBusinessClient client, string strTimestamp, string strNonce, string strContent, string strSignature, string strSignatureAlgorithm, string strSerialNumber, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
- switch (strSignAlgorithm)
+ switch (strSignatureAlgorithm)
{
case Constants.SignAlgorithms.SHA245_WITH_RSA:
{
@@ -80,7 +67,7 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
error = null;
return Utilities.RSAUtility.VerifyWithSHA256(
publicKey: client.Credentials.TBEPCertificatePublicKey,
- plainText: GetPlainTextForSignature(timestamp: strTimestamp, nonce: strNonce, body: strBody),
+ message: GetPlainTextForSignature(timestamp: strTimestamp, nonce: strNonce, body: strContent),
signature: strSignature
);
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientEventVerificationExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientEventVerificationExtensions.cs
index 748689ca..2df5bdf2 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientEventVerificationExtensions.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientEventVerificationExtensions.cs
@@ -30,9 +30,18 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
if (callbackAuthorization == null) throw new ArgumentNullException(nameof(callbackAuthorization));
if (callbackBody == null) throw new ArgumentNullException(nameof(callbackBody));
- bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(client, callbackAuthorization, callbackBody, out error);
+ bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(
+ client,
+ strAuthorization: callbackAuthorization,
+ strContent: callbackBody,
+ out error
+ );
+
if (error != null)
+ {
error = new Exceptions.WechatTenpayBusinessEventVerificationException("Verify signature of event failed. Please see the `InnerException` for more details.", error);
+ }
+
return ret;
}
@@ -48,7 +57,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
///
public static bool VerifyEventSignature(this WechatTenpayBusinessClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSerialNumber)
{
- return VerifyEventSignature(client, callbackTimestamp, callbackNonce, callbackBody, callbackSignature, callbackSerialNumber, Constants.SignAlgorithms.SHA245_WITH_RSA, out _);
+ return VerifyEventSignature(
+ client,
+ callbackTimestamp: callbackTimestamp,
+ callbackNonce: callbackNonce,
+ callbackBody: callbackBody,
+ callbackSignature: callbackSignature,
+ callbackSignatureAlgorithm: Constants.SignAlgorithms.SHA245_WITH_RSA,
+ callbackSerialNumber: callbackSerialNumber,
+ out _
+ );
}
///
@@ -59,12 +77,21 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
/// 。
///
///
+ ///
///
- ///
///
- public static bool VerifyEventSignature(this WechatTenpayBusinessClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSerialNumber, string callbackSignAlgorithm)
+ public static bool VerifyEventSignature(this WechatTenpayBusinessClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSignatureAlgorithm, string callbackSerialNumber)
{
- return VerifyEventSignature(client, callbackTimestamp, callbackNonce, callbackBody, callbackSignature, callbackSerialNumber, callbackSignAlgorithm, out _);
+ return VerifyEventSignature(
+ client,
+ callbackTimestamp: callbackTimestamp,
+ callbackNonce: callbackNonce,
+ callbackBody: callbackBody,
+ callbackSignature: callbackSignature,
+ callbackSignatureAlgorithm: callbackSignatureAlgorithm,
+ callbackSerialNumber: callbackSerialNumber,
+ out _
+ );
}
///
@@ -81,7 +108,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
///
public static bool VerifyEventSignature(this WechatTenpayBusinessClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSerialNumber, out Exception? error)
{
- return VerifyEventSignature(client, callbackTimestamp, callbackNonce, callbackBody, callbackSignature, callbackSerialNumber, Constants.SignAlgorithms.SHA245_WITH_RSA, out error);
+ return VerifyEventSignature(
+ client,
+ callbackTimestamp: callbackTimestamp,
+ callbackNonce: callbackNonce,
+ callbackBody: callbackBody,
+ callbackSignature: callbackSignature,
+ callbackSignatureAlgorithm: Constants.SignAlgorithms.SHA245_WITH_RSA,
+ callbackSerialNumber: callbackSerialNumber,
+ out error
+ );
}
///
@@ -92,18 +128,31 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
/// 。
///
///
+ ///
///
- ///
///
///
///
- public static bool VerifyEventSignature(this WechatTenpayBusinessClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSerialNumber, string callbackSignAlgorithm, out Exception? error)
+ public static bool VerifyEventSignature(this WechatTenpayBusinessClient client, string callbackTimestamp, string callbackNonce, string callbackBody, string callbackSignature, string callbackSignatureAlgorithm, string callbackSerialNumber, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
- bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(client, callbackTimestamp, callbackNonce, callbackBody, callbackSignature, callbackSerialNumber, callbackSignAlgorithm, out error);
+ bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(
+ client,
+ strTimestamp: callbackTimestamp,
+ strNonce: callbackNonce,
+ strContent: callbackBody,
+ strSignature: callbackSignature,
+ strSignatureAlgorithm: callbackSignatureAlgorithm,
+ strSerialNumber: callbackSerialNumber,
+ out error
+ );
+
if (error != null)
+ {
error = new Exceptions.WechatTenpayBusinessEventVerificationException("Verify signature of event failed. Please see the `InnerException` for more details.", error);
+ }
+
return ret;
}
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs
index 87856814..2416d20b 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Extensions/WechatTenpayBusinessClientResponseVerificationExtensions.cs
@@ -32,11 +32,18 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
{
if (client == null) throw new ArgumentNullException(nameof(client));
- string? responseAuthHeader = response.RawHeaders.FirstOrDefault(e => string.Equals(e.Key, "TBEP-Authorization", StringComparison.OrdinalIgnoreCase)).Value;
- string responseBody = Encoding.UTF8.GetString(response.RawBytes);
- bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(client, responseAuthHeader, responseBody, out error);
+ bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(
+ client,
+ strAuthorization: response.RawHeaders.FirstOrDefault(e => string.Equals(e.Key, "TBEP-Authorization", StringComparison.OrdinalIgnoreCase)).Value,
+ strContent: Encoding.UTF8.GetString(response.RawBytes),
+ out error
+ );
+
if (error != null)
+ {
error = new Exceptions.WechatTenpayBusinessResponseVerificationException("Verify signature of response failed. Please see the `InnerException` for more details.", error);
+ }
+
return ret;
}
@@ -52,7 +59,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
///
public static bool VerifyResponseSignature(this WechatTenpayBusinessClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSerialNumber)
{
- return VerifyResponseSignature(client, responseTimestamp, responseNonce, responseBody, responseSignature, responseSerialNumber, Constants.SignAlgorithms.SHA245_WITH_RSA, out _);
+ return VerifyResponseSignature(
+ client,
+ responseTimestamp: responseTimestamp,
+ responseNonce: responseNonce,
+ responseBody: responseBody,
+ responseSignature: responseSignature,
+ responseSignatureAlgorithm: Constants.SignAlgorithms.SHA245_WITH_RSA,
+ responseSerialNumber: responseSerialNumber,
+ out _
+ );
}
///
@@ -63,12 +79,21 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
/// 。
///
///
+ ///
///
- ///
///
- public static bool VerifyResponseSignature(this WechatTenpayBusinessClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSerialNumber, string responseSignAlgorithm)
+ public static bool VerifyResponseSignature(this WechatTenpayBusinessClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSignatureAlgorithm, string responseSerialNumber)
{
- return VerifyResponseSignature(client, responseTimestamp, responseNonce, responseBody, responseSignature, responseSerialNumber, responseSignAlgorithm, out _);
+ return VerifyResponseSignature(
+ client,
+ responseTimestamp: responseTimestamp,
+ responseNonce: responseNonce,
+ responseBody: responseBody,
+ responseSignature: responseSignature,
+ responseSignatureAlgorithm: responseSignatureAlgorithm,
+ responseSerialNumber: responseSerialNumber,
+ out _
+ );
}
///
@@ -84,7 +109,16 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
///
public static bool VerifyResponseSignature(this WechatTenpayBusinessClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSerialNumber, out Exception? error)
{
- return VerifyResponseSignature(client, responseTimestamp, responseNonce, responseBody, responseSignature, responseSerialNumber, Constants.SignAlgorithms.SHA245_WITH_RSA, out error);
+ return VerifyResponseSignature(
+ client,
+ responseTimestamp: responseTimestamp,
+ responseNonce: responseNonce,
+ responseBody: responseBody,
+ responseSignature: responseSignature,
+ responseSignatureAlgorithm: Constants.SignAlgorithms.SHA245_WITH_RSA,
+ responseSerialNumber: responseSerialNumber,
+ out error
+ );
}
///
@@ -95,17 +129,30 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness
/// 。
///
///
+ ///
///
- ///
///
///
- public static bool VerifyResponseSignature(this WechatTenpayBusinessClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSerialNumber, string responseSignAlgorithm, out Exception? error)
+ public static bool VerifyResponseSignature(this WechatTenpayBusinessClient client, string responseTimestamp, string responseNonce, string responseBody, string responseSignature, string responseSignatureAlgorithm, string responseSerialNumber, out Exception? error)
{
if (client == null) throw new ArgumentNullException(nameof(client));
- bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(client, responseTimestamp, responseNonce, responseBody, responseSignature, responseSerialNumber, responseSignAlgorithm, out error);
+ bool ret = WechatTenpayBusinessClientSignExtensions.VerifySignature(
+ client,
+ strTimestamp: responseTimestamp,
+ strNonce: responseNonce,
+ strContent: responseBody,
+ strSignature: responseSignature,
+ strSignatureAlgorithm: responseSignatureAlgorithm,
+ strSerialNumber: responseSerialNumber,
+ out error
+ );
+
if (error != null)
+ {
error = new Exceptions.WechatTenpayBusinessResponseVerificationException("Verify signature of response failed. Please see the `InnerException` for more details.", error);
+ }
+
return ret;
}
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs
index 2ffcd86f..58af4a62 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/RSAUtility.cs
@@ -16,35 +16,83 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
private const string RSA_CIPHER_PADDING_OAEP_WITH_SHA1_AND_MGF1 = "OAEPWITHSHA1ANDMGF1PADDING";
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 byte[] SignWithSHA256(RsaKeyParameters rsaPrivateKeyParams, byte[] msgBytes)
+ {
+ ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256);
+ signer.Init(true, rsaPrivateKeyParams);
+ signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
+ return signer.GenerateSignature();
+ }
+
+ private static bool VerifyWithSHA256(RsaKeyParameters rsaPublicKeyParams, byte[] msgBytes, byte[] signBytes)
+ {
+ ISigner signer = SignerUtilities.GetSigner(RSA_SIGNER_ALGORITHM_SHA256);
+ signer.Init(false, rsaPublicKeyParams);
+ signer.BlockUpdate(msgBytes, 0, msgBytes.Length);
+ return signer.VerifySignature(signBytes);
+ }
+
+ private static byte[] DecryptWithECB(RsaKeyParameters rsaPrivateKeyParams, byte[] cipherBytes, string paddingAlgorithm)
+ {
+ IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingAlgorithm}");
+ cipher.Init(false, rsaPrivateKeyParams);
+ return cipher.DoFinal(cipherBytes);
+ }
+
+ private static byte[] EncryptWithECB(RsaKeyParameters rsaPublicKeyParams, byte[] msgBytes, string paddingAlgorithm)
+ {
+ IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingAlgorithm}");
+ cipher.Init(true, rsaPublicKeyParams);
+ return cipher.DoFinal(msgBytes);
+ }
+
///
/// 使用私钥基于 SHA-256 算法生成签名。
///
/// PKCS#8 私钥字节数组。
- /// 待签名的数据字节数组。
+ /// 待签名的数据字节数组。
/// 签名字节数组。
- public static byte[] SignWithSHA256(byte[] privateKeyBytes, byte[] plainBytes)
+ public static byte[] SignWithSHA256(byte[] privateKeyBytes, byte[] msgBytes)
{
if (privateKeyBytes == null) throw new ArgumentNullException(nameof(privateKeyBytes));
- if (plainBytes == null) throw new ArgumentNullException(nameof(plainBytes));
+ if (msgBytes == null) throw new ArgumentNullException(nameof(msgBytes));
RsaKeyParameters rsaKeyParams = (RsaKeyParameters)PrivateKeyFactory.CreateKey(privateKeyBytes);
- return SignWithSHA256(rsaKeyParams, plainBytes);
+ return SignWithSHA256(rsaKeyParams, msgBytes);
}
///
/// 使用私钥基于 SHA-256 算法生成签名。
///
/// PKCS#8 私钥(PEM 格式)。
- /// 待签名的文本数据。
+ /// 待签名的文本数据。
/// 经 Base64 编码的签名。
- public static string SignWithSHA256(string privateKey, string plainText)
+ public static string SignWithSHA256(string privateKey, string message)
{
if (privateKey == null) throw new ArgumentNullException(nameof(privateKey));
- if (plainText == null) throw new ArgumentNullException(nameof(plainText));
+ if (message == null) throw new ArgumentNullException(nameof(message));
byte[] privateKeyBytes = ConvertPkcs8PrivateKeyToByteArray(privateKey);
- byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
- byte[] signBytes = SignWithSHA256(privateKeyBytes, plainBytes);
+ byte[] msgBytes = Encoding.UTF8.GetBytes(message);
+ byte[] signBytes = SignWithSHA256(privateKeyBytes, msgBytes);
return Convert.ToBase64String(signBytes);
}
@@ -52,36 +100,36 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
/// 使用公钥基于 SHA-256 算法验证签名。
///
/// PKCS#8 公钥字节数据。
- /// 待验证的数据字节数据。
+ /// 待验证的数据字节数据。
/// 待验证的签名字节数据。
/// 验证结果。
- public static bool VerifyWithSHA256(byte[] publicKeyBytes, byte[] plainBytes, byte[] signBytes)
+ public static bool VerifyWithSHA256(byte[] publicKeyBytes, byte[] msgBytes, byte[] signBytes)
{
if (publicKeyBytes == null) throw new ArgumentNullException(nameof(publicKeyBytes));
- if (plainBytes == null) throw new ArgumentNullException(nameof(plainBytes));
+ if (msgBytes == null) throw new ArgumentNullException(nameof(msgBytes));
if (signBytes == null) throw new ArgumentNullException(nameof(signBytes));
RsaKeyParameters rsaKeyParams = (RsaKeyParameters)PublicKeyFactory.CreateKey(publicKeyBytes);
- return VerifyWithSHA256(rsaKeyParams, plainBytes, signBytes);
+ return VerifyWithSHA256(rsaKeyParams, msgBytes, signBytes);
}
///
/// 使用公钥基于 SHA-256 算法验证签名。
///
/// PKCS#8 公钥(PEM 格式)。
- /// 待验证的文本数据。
+ /// 待验证的文本数据。
/// 经 Base64 编码的待验证的签名。
/// 验证结果。
- public static bool VerifyWithSHA256(string publicKey, string plainText, string signature)
+ public static bool VerifyWithSHA256(string publicKey, string message, string signature)
{
if (publicKey == null) throw new ArgumentNullException(nameof(publicKey));
- if (plainText == null) throw new ArgumentNullException(nameof(plainText));
+ if (message == null) throw new ArgumentNullException(nameof(message));
if (signature == null) throw new ArgumentNullException(nameof(signature));
byte[] publicKeyBytes = ConvertPkcs8PublicKeyToByteArray(publicKey);
- byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
+ byte[] msgBytes = Encoding.UTF8.GetBytes(message);
byte[] signBytes = Convert.FromBase64String(signature);
- return VerifyWithSHA256(publicKeyBytes, plainBytes, signBytes);
+ return VerifyWithSHA256(publicKeyBytes, msgBytes, signBytes);
}
///
@@ -151,53 +199,5 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
byte[] cipherBytes = EncryptWithECB(publicKeyBytes, plainBytes, paddingAlgorithm);
return Convert.ToBase64String(cipherBytes);
}
-
- 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 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 paddingAlgorithm)
- {
- IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingAlgorithm}");
- cipher.Init(true, rsaKeyParams);
- return cipher.DoFinal(plainBytes);
- }
-
- private static byte[] DecryptWithECB(RsaKeyParameters rsaKeyParams, byte[] cipherBytes, string paddingAlgorithm)
- {
- IBufferedCipher cipher = CipherUtilities.GetCipher($"{RSA_CIPHER_ALGORITHM_ECB}/{paddingAlgorithm}");
- cipher.Init(false, rsaKeyParams);
- return cipher.DoFinal(cipherBytes);
- }
}
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs
index c09b7ed4..0165cfd7 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayBusiness/Utilities/SM3Utility.cs
@@ -7,7 +7,40 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
///
/// SM3 算法工具类。
///
- public static class SM3Utility
+ public static partial class SM3Utility
+ {
+ ///
+ /// 获取 SM3 哈希值。
+ ///
+ /// 信息字节数组。
+ /// 哈希字节数组。
+ public static byte[] Hash(byte[] bytes)
+ {
+ if (bytes == null) throw new ArgumentNullException(nameof(bytes));
+
+ SM3Digest sm3 = new SM3Digest();
+ sm3.BlockUpdate(bytes, 0, bytes.Length);
+ byte[] hashBytes = new byte[sm3.GetDigestSize()];
+ sm3.DoFinal(hashBytes, 0);
+ return hashBytes;
+ }
+
+ ///
+ /// 获取 SM3 哈希值。
+ ///
+ /// 文本信息。
+ /// 哈希值。
+ public static string Hash(string message)
+ {
+ if (message == null) throw new ArgumentNullException(nameof(message));
+
+ byte[] msgBytes = Encoding.UTF8.GetBytes(message);
+ byte[] hashBytes = Hash(msgBytes);
+ return BitConverter.ToString(hashBytes).Replace("-", string.Empty);
+ }
+ }
+
+ partial class SM3Utility
{
internal static class BitOperator
{
@@ -336,35 +369,5 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayBusiness.Utilities
return DIGEST_LENGTH;
}
}
-
- ///
- /// 获取 SM3 哈希值。
- ///
- /// 信息字节数组。
- /// 哈希字节数组。
- public static byte[] Hash(byte[] bytes)
- {
- if (bytes == null) throw new ArgumentNullException(nameof(bytes));
-
- SM3Digest sm3 = new SM3Digest();
- sm3.BlockUpdate(bytes, 0, bytes.Length);
- byte[] hashBytes = new byte[sm3.GetDigestSize()];
- sm3.DoFinal(hashBytes, 0);
- return hashBytes;
- }
-
- ///
- /// 获取 SM3 哈希值。
- ///
- /// 文本信息。
- /// 哈希值。
- public static string Hash(string message)
- {
- if (message == null) throw new ArgumentNullException(nameof(message));
-
- byte[] msgBytes = Encoding.UTF8.GetBytes(message);
- byte[] hashBytes = Hash(msgBytes);
- return BitConverter.ToString(hashBytes).Replace("-", string.Empty);
- }
}
}
diff --git a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SM3Utility.cs b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SM3Utility.cs
index 22730c36..4a470402 100644
--- a/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SM3Utility.cs
+++ b/src/SKIT.FlurlHttpClient.Wechat.TenpayV3/Utilities/SM3Utility.cs
@@ -7,7 +7,40 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
///
/// SM3 算法工具类。
///
- public static class SM3Utility
+ public static partial class SM3Utility
+ {
+ ///
+ /// 获取 SM3 哈希值。
+ ///
+ /// 信息字节数组。
+ /// 哈希字节数组。
+ public static byte[] Hash(byte[] bytes)
+ {
+ if (bytes == null) throw new ArgumentNullException(nameof(bytes));
+
+ SM3Digest sm3 = new SM3Digest();
+ sm3.BlockUpdate(bytes, 0, bytes.Length);
+ byte[] hashBytes = new byte[sm3.GetDigestSize()];
+ sm3.DoFinal(hashBytes, 0);
+ return hashBytes;
+ }
+
+ ///
+ /// 获取 SM3 哈希值。
+ ///
+ /// 文本信息。
+ /// 哈希值。
+ public static string Hash(string message)
+ {
+ if (message == null) throw new ArgumentNullException(nameof(message));
+
+ byte[] msgBytes = Encoding.UTF8.GetBytes(message);
+ byte[] hashBytes = Hash(msgBytes);
+ return BitConverter.ToString(hashBytes).Replace("-", string.Empty);
+ }
+ }
+
+ partial class SM3Utility
{
internal static class BitOperator
{
@@ -336,35 +369,5 @@ namespace SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities
return DIGEST_LENGTH;
}
}
-
- ///
- /// 获取 SM3 哈希值。
- ///
- /// 信息字节数组。
- /// 哈希字节数组。
- public static byte[] Hash(byte[] bytes)
- {
- if (bytes == null) throw new ArgumentNullException(nameof(bytes));
-
- SM3Digest sm3 = new SM3Digest();
- sm3.BlockUpdate(bytes, 0, bytes.Length);
- byte[] hashBytes = new byte[sm3.GetDigestSize()];
- sm3.DoFinal(hashBytes, 0);
- return hashBytes;
- }
-
- ///
- /// 获取 SM3 哈希值。
- ///
- /// 文本信息。
- /// 哈希值。
- public static string Hash(string message)
- {
- if (message == null) throw new ArgumentNullException(nameof(message));
-
- byte[] msgBytes = Encoding.UTF8.GetBytes(message);
- byte[] hashBytes = Hash(msgBytes);
- return BitConverter.ToString(hashBytes).Replace("-", string.Empty);
- }
}
}