74 lines
2.7 KiB
C#
74 lines
2.7 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Security.Cryptography;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace New_College.Common.Helper
|
||
{
|
||
|
||
public class WeChatPaySignatureValidator
|
||
{
|
||
private readonly string appId;
|
||
private readonly string mchId;
|
||
private readonly string apiKey;
|
||
|
||
//public WeChatPaySignatureValidator(string appId, string mchId, string apiKey)
|
||
//{
|
||
// this.appId = appId;
|
||
// this.mchId = mchId;
|
||
// this.apiKey = apiKey;
|
||
//}
|
||
|
||
public static bool VerifySignature(string returnCode, string returnMsg, string appId, string mchId, string nonceStr, string sign, string resultCode)
|
||
{
|
||
// 获取微信支付回调的全部参数,包括商户自定义参数等。
|
||
var allParams = new SortedDictionary<string, string>
|
||
{
|
||
{"return_code", returnCode},
|
||
{"return_msg", returnMsg},
|
||
{"appid", appId},
|
||
{"mch_id", mchId},
|
||
{"nonce_str", nonceStr},
|
||
{"sign", sign},
|
||
{"result_code", resultCode}
|
||
// 这里可以添加其他商户自定义的参数,并按照字典序排序。
|
||
};
|
||
|
||
// 将所有参数按照键值对的形式拼接成一个字符串。
|
||
var strToBeSigned = JoinByKey(allParams);
|
||
|
||
// 验证签名,如果验证通过则返回true,否则返回false。
|
||
return CheckSignature(strToBeSigned, WeixinConfig.APIv3Key);
|
||
}
|
||
|
||
private static string JoinByKey(SortedDictionary<string, string> dict)
|
||
{
|
||
var sb = new StringBuilder();
|
||
foreach (var kv in dict)
|
||
{
|
||
sb.Append(kv.Key);
|
||
sb.Append("=");
|
||
sb.Append(kv.Value);
|
||
sb.Append("&");
|
||
}
|
||
// 去掉最后一个"&"字符。
|
||
if (sb.Length > 0) sb.Length -= 1;
|
||
return sb.ToString();
|
||
}
|
||
|
||
private static bool CheckSignature(string strToBeSigned, string apiSecret)
|
||
{
|
||
// 使用商户的API密钥进行签名验证。这里使用SHA256算法进行加密。
|
||
using (var sha256 = SHA256.Create())
|
||
{
|
||
var dataToBeSigned = Encoding.UTF8.GetBytes(strToBeSigned);
|
||
var dataSigned = sha256.ComputeHash(dataToBeSigned);
|
||
var dataSignedBase64 = Convert.ToBase64String(dataSigned);
|
||
return apiSecret == dataSignedBase64; // 这里将签名结果与商户的API密钥进行比对。如果比对成功,则签名验证通过。
|
||
}
|
||
}
|
||
}
|
||
}
|