C#.NET XML报文签名与验签

--

MD5Util:

using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text; namespace dotNetRsa客户端
{
public class MD5Util
{
/// <summary>
/// mdh5 hash, UTF8 , 16进制表示,去除 "-" 符号,大写
/// </summary>
/// <param name="sArray"></param>
/// <returns></returns>
public static string GetMD5(string sArray,string charset)
{ Encoding enc = Encoding.GetEncoding(charset); byte[] sourceBytes = enc.GetBytes(sArray); MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
byte[] hashedBytes = md5.ComputeHash(sourceBytes); string str16 = BitConverter.ToString(hashedBytes); string rst = str16.Replace("-", "").ToUpper(); return rst;
}
}
}

--

Utils:

using System;
using System.Collections.Generic;
using System.Text;
using System.Web; namespace dotNetRsa客户端
{
public class Utils
{
public static string UrlEncode(string temp, string charset )
{ Encoding encoding = Encoding.GetEncoding(charset);
StringBuilder stringBuilder = new StringBuilder();
for (int i = ; i < temp.Length; i++)
{
string t = temp[i].ToString();
string k = HttpUtility.UrlEncode(t, encoding);
if (t == k)
{
stringBuilder.Append(t);
}
else
{
stringBuilder.Append(k.ToUpper());
}
}
return stringBuilder.ToString();
} }
}

--

RequestHandlerB:

--

using System;
using System.Collections;
using System.Collections.Generic; using System.Text;
using System.Text.RegularExpressions; using System.Web;
using System.Xml; namespace dotNetRsa客户端
{
/// <summary>
/// 能处理请求报文和响应报文
/// </summary>
public class RequestHandlerB
{ /// <summary>
/// 原始内容
/// </summary>
protected string content; public RequestHandlerB()
{
parameters = new Hashtable(); // this.httpContext = httpContext;
} /// <summary>
/// 网关url地址
/// </summary>
private string gateUrl; /// <summary>
/// 密钥
/// </summary>
private string key; /// <summary>
/// 请求的参数
/// </summary>
protected Hashtable parameters; /// <summary>
/// debug信息
/// </summary>
private string debugInfo; /// <summary>
/// 初始化函数
/// </summary>
public virtual void init()
{
//nothing to do
} /// <summary>
/// 获取入口地址,不包含参数值
/// </summary>
/// <returns></returns>
public String getGateUrl()
{
return gateUrl;
} /// <summary>
/// 设置入口地址,不包含参数值
/// </summary>
/// <param name="gateUrl">入口地址</param>
public void setGateUrl(String gateUrl)
{
this.gateUrl = gateUrl;
} /// <summary>
/// 获取密钥
/// </summary>
/// <returns></returns>
public String getKey()
{
return key;
} /// <summary>
/// 设置密钥
/// </summary>
/// <param name="key">密钥字符串</param>
public void setKey(string key)
{
this.key = key;
} /// <summary>
/// 获取带参数的请求URL
/// </summary>
/// <returns></returns>
public virtual string getRequestURL()
{
this.createSign(); StringBuilder sb = new StringBuilder();
ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort();
foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "key".CompareTo(k) != )
{
sb.Append(k + "=" + Utils.UrlEncode(v, getCharset()) + "&");
}
} //去掉最后一个&
if (sb.Length > )
{
sb.Remove(sb.Length - , );
} return this.getGateUrl() + "?" + sb.ToString();
} /// <summary>
///创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
/// </summary>
public virtual void createSign()
{
StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) != && "key".CompareTo(k) != )
{
sb.Append(k + "=" + v + "&");
}
} sb.Append("key=" + this.getKey()); string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); this.setParameter("sign", sign); //debug信息
this.setDebugInfo(sb.ToString() + " => sign:" + sign);
} /// <summary>
/// 没有KEY的拼接和MD5 HASH 签名
/// </summary>
public virtual void createSignWithoutKey()
{
StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) != && "key".CompareTo(k) != )
{
sb.Append(k + "=" + v + "&");
}
} string rst = sb.ToString();
rst = rst.TrimEnd('&'); // sb.Append("key=" + this.getKey()); string sign = MD5Util.GetMD5(rst, getCharset()).ToUpper(); this.setParameter("sign", sign); //debug信息
this.setDebugInfo(sb.ToString() + " => sign:" + sign);
} /// <summary>
/// 获取参数值
/// </summary>
/// <param name="parameter">参数名</param>
/// <returns></returns>
public string getParameter(string parameter)
{
string s = (string)parameters[parameter];
return (null == s) ? "" : s;
} /// <summary>
/// 设置参数值
/// </summary>
/// <param name="parameter">参数名</param>
/// <param name="parameterValue">参数值</param>
public void setParameter(string parameter, string parameterValue)
{
if (parameter != null && parameter != "")
{
if (parameters.Contains(parameter))
{
parameters.Remove(parameter);
} parameters.Add(parameter, parameterValue);
}
} /// <summary>
/// 获取debug信息
/// </summary>
/// <returns></returns>
public String getDebugInfo()
{
return debugInfo;
} /// <summary>
/// 设置debug信息
/// </summary>
/// <param name="debugInfo"></param>
public void setDebugInfo(String debugInfo)
{
this.debugInfo = debugInfo;
} /// <summary>
/// 获取所有参数
/// </summary>
/// <returns></returns>
public Hashtable getAllParameters()
{
return this.parameters;
} /// <summary>
/// 获取编码
/// </summary>
/// <returns></returns>
protected virtual string getCharset()
{
//return this.httpContext.Request.ContentEncoding.BodyName;
return "utf-8";
} public virtual void createSignMCH()
{ /*
1.进件接口用 用的是dataSign,不是sign
2.拼接key时,不需要&key=
*/ StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) != && "key".CompareTo(k) != )
{
sb.Append(k + "=" + v + "&");
}
} string sighStr = sb.ToString();
sighStr = sighStr.TrimEnd('&');
sighStr += this.getKey();//和支付接口不同 string sign = MD5Util.GetMD5(sighStr, getCharset()).ToLower(); this.setParameter("dataSign", sign); //debug信息
this.setDebugInfo(sb.ToString() + " => dataSign:" + sign);
} //创建md5摘要,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。 //public string createSign2()
//{
// StringBuilder sb = new StringBuilder(); // ArrayList akeys = new ArrayList(parameters.Keys);
// akeys.Sort(); // foreach (string k in akeys)
// {
// string v = (string)parameters[k];
// if (null != v && "".CompareTo(v) != 0
// && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
// {
// sb.Append(k + "=" + v + "&");
// }
// } // sb.Append("key=" + this.getKey());
// string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); // this.setParameter("sign", sign); // return sign;
//} //输出XML
public string parseXML()
{
StringBuilder sb = new StringBuilder();
sb.Append("<xml>");
foreach (string k in parameters.Keys)
{
string v = (string)parameters[k];
if (Regex.IsMatch(v, @"^[0-9.]$"))
{ sb.Append("<" + k + ">" + v + "</" + k + ">");
}
else
{
sb.Append("<" + k + "><![CDATA[" + v + "]]></" + k + ">");
} }
sb.Append("</xml>");
return sb.ToString();
} /// <summary>
/// 设置返回内容
/// </summary>
/// <param name="content">XML内容</param>
public virtual void setContent(string content)
{
this.content = content;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.XmlResolver = null;//2018-12-3
xmlDoc.LoadXml(content);
XmlNode root = xmlDoc.SelectSingleNode("xml");
XmlNodeList xnl = root.ChildNodes; foreach (XmlNode xnf in xnl)
{
this.setParameter(xnf.Name, xnf.InnerText);
}
} /// <summary>
/// 是否平台签名,规则是:按参数名称a-z排序,遇到空值的参数不参加签名。
/// </summary>
/// <returns></returns>
public virtual Boolean isTenpaySign()
{
StringBuilder sb = new StringBuilder(); ArrayList akeys = new ArrayList(parameters.Keys);
akeys.Sort(); foreach (string k in akeys)
{
string v = (string)parameters[k];
if (null != v && "".CompareTo(v) !=
&& "sign".CompareTo(k) != && "key".CompareTo(k) != )
{
sb.Append(k + "=" + v + "&");
}
} sb.Append("key=" + this.getKey());
string sign = MD5Util.GetMD5(sb.ToString(), getCharset()).ToUpper(); //debug信息
this.setDebugInfo(sb.ToString() + " => sign:" + sign);
return getParameter("sign").Equals(sign);
} }
}

--

xml root 为"xml"。

使用,签名:

 RequestHandlerB rb = new RequestHandlerB();
rb.setKey("1111111111111111XXXXXXXXXXXXX"); //设置KEY
rb.setParameter("custno", "");
rb.setParameter("shopname", "");
rb.setParameter("type", "");
rb.setParameter("serialno", "");
rb.createSign(); //签名
string xmlb = rb.parseXML(); // 转XML

验证签名

 RequestHandlerB rb2 = new RequestHandlerB();
rb2.setKey("1111111111111111XXXXXXXXXXXXX");
rb2.setContent(xmlb);
bool isvalid = rb2.isTenpaySign();

--

上一篇:【十大经典数据挖掘算法】PageRank


下一篇:在unity3d中使用opencv