Files
juipnet/Services/Hncore.Pass.PaymentCenter/Pay/WxPay/WxJsPayData.cs
wanyongkang d318014316 初始提交
2020-10-07 20:25:03 +08:00

166 lines
5.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using Hncore.Infrastructure.Common;
using Hncore.Infrastructure.Extension;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Xml;
namespace Hncore.Pass.PaymentCenter.WxPay.WechatJsPay
{
/// <summary>
/// 微信小程序、公众号支付H5支付 数据签名校验
/// </summary>
public class WxPayChecker: SortedDictionary<string, string>
{
public string SignType { get; set; } = "MD5";// "HMAC-SHA256";
public string MchKey { get; set; }
/**
* 生成时间戳标准北京时间时区为东八区自1970年1月1日 0点0分0秒以来的秒数
* @return 时间戳
*/
public string GenerateTimeStamp()
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
/**
* 生成随机串,随机串包含字母或数字
* @return 随机串
*/
public string GenerateNonceStr()
{
return Guid.NewGuid().ToString("N");
}
public virtual string CreateSign()
{
string sign = "";
foreach (var item in this)
{
if (item.Key == "sign"|| item.Key == "paySign") continue;
sign += item.Key + "=" + item.Value + "&";
}
if(this.MchKey.Has())
sign += "key=" + this.MchKey;
LogHelper.Trace("CreateSign Str", sign);
if (SignType == "MD5")
{
sign = SecurityHelper.GetMd5Hash(sign);
}
else if (SignType == "HMAC-SHA256")
{
sign = CalcHMACSHA256Hash(sign, this.MchKey);
}
this["sign"] = sign;
return sign;
}
public bool IsSet(string key)
{
if (!this.ContainsKey(key)) return false;
return this[key].Has();
}
public virtual bool CheckSign()
{
//如果没有设置签名,则跳过检测
if (!this.IsSet("sign"))
{
LogHelper.Error("CheckSign", "签名不存在!");
return false;
}
//获取接收到的签名
string return_sign = this["sign"];
//在本地计算新的签名
string cal_sign = CreateSign();
if (cal_sign == return_sign)
{
return true;
}
return true;
}
private string CalcHMACSHA256Hash(string plaintext, string salt)
{
string result = "";
var enc = Encoding.Default;
byte[]
baText2BeHashed = enc.GetBytes(plaintext),
baSalt = enc.GetBytes(salt);
System.Security.Cryptography.HMACSHA256 hasher = new HMACSHA256(baSalt);
byte[] baHashedText = hasher.ComputeHash(baText2BeHashed);
result = string.Join("", baHashedText.ToList().Select(b => b.ToString("x2")).ToArray());
return result;
}
public string ToXml()
{
CreateSign();
StringBuilder sb = new StringBuilder("<xml>\n");
foreach (var item in this)
{
string key = item.Key;
sb.Append("\t<").Append(key).Append("><![CDATA[").Append(item.Value).Append("]]></").Append(key)
.Append(">\n");
}
return sb.Append("</xml>").ToString();
}
public WxPayChecker FromXml(string xml)
{
if (string.IsNullOrEmpty(xml))
{
return null;
}
LogHelper.Info("FromXml", xml);
this.Clear();
XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null };
xmlDoc.LoadXml(xml);
XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
XmlNodeList nodes = xmlNode.ChildNodes;
foreach (XmlNode xn in nodes)
{
XmlElement xe = (XmlElement)xn;
this[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
}
if (!CheckSign())
{
return null;
}
return this;
}
public WxPayChecker FromXmlNoCheckSign(string xml)
{
if (string.IsNullOrEmpty(xml))
{
return null;
}
LogHelper.Info("FromXml", xml);
this.Clear();
XmlDocument xmlDoc = new XmlDocument() { XmlResolver = null };
xmlDoc.LoadXml(xml);
XmlNode xmlNode = xmlDoc.FirstChild;//获取到根节点<xml>
XmlNodeList nodes = xmlNode.ChildNodes;
foreach (XmlNode xn in nodes)
{
XmlElement xe = (XmlElement)xn;
this[xe.Name] = xe.InnerText;//获取xml的键值对到WxPayData内部的数据中
}
return this;
}
}
}