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();
--
C#.NET XML报文签名与验签的更多相关文章
- .NET RSA解密、签名、验签
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Sec ...
- PHP SHA1withRSA加密生成签名及验签
最近公司对接XX第三方支付平台的代付业务,由于对方公司只有JAVA的demo,所以只能根据文档自己整合PHP的签名加密,网上找过几个方法,踩到各种各样的坑,还好最后算是搞定了,话不多说,代码分享出来. ...
- 中行P1签名及验签
分享中国银行快捷.NET P1签名和验签方法代码中ReturnValue为自定义类型请无视 #region 验证签名 /// <summary> /// 验证签名 /// </sum ...
- 几个例子理解对称加密与非对称加密、公钥与私钥、签名与验签、数字证书、HTTPS加密方式
# 原创,转载请留言联系 为什么会出现这么多加密啊,公钥私钥啊,签名啊这些东西呢?说到底还是保证双方通信的安全性与完整性.例如小明发一封表白邮件给小红,他总不希望给别人看见吧.而各种各样的技术就是为了 ...
- erlang的RSA签名与验签
1.RSA介绍 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对 其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而 ...
- Delphi微信支付【支持MD5和HMAC-SHA256签名与验签】
作者QQ:(648437169) 点击下载➨微信支付 微信支付api文档 [Delphi 微信支付]支持付款码支付.二维码支付.订单查询.申请退款.退款查询.撤销订单.关闭订单. ...
- Delphi支付宝支付【支持SHA1WithRSA(RSA)和SHA256WithRSA(RSA2)签名与验签】
作者QQ:(648437169) 点击下载➨Delphi支付宝支付 支付宝支付api文档 [Delphi支付宝支付]支持条码支付.扫码支付.交易查询.交易退款.退款查询.交易撤 ...
- RSA后台签名前台验签的应用(前台采用jsrsasign库)
写在前面 安全测试需要, 为防止后台响应数据返给前台过程中被篡改前台再拿被篡改后的数据进行接下来的操作影响正常业务, 决定采用RSA对响应数据进行签名和验签, 于是有了这篇<RSA后台签名前台验 ...
- Delphi RSA签名与验签【支持SHA1WithRSA(RSA1)、SHA256WithRSA(RSA2)和MD5WithRSA签名与验签】
作者QQ:(648437169) 点击下载➨ RSA签名与验签 [delphi RSA签名与验签]支持3种方式签名与验签(SHA1WithRSA(RSA1).SHA256WithRSA(RSA2)和M ...
随机推荐
- android -------- MVP+DataBinding 的使用
今天来说说MVP+DataBinding 的使用 以一个登录案例来讲解 布局:(ConstraintLayout 作为根布局) <layout> <data> <vari ...
- Tinkoff Internship Warmup Round 2018 and Codeforces Round #475 (Div. 1)D. Frequency of String
题意:有一个串s,n个串模式串t,问s的子串中长度最小的包含t k次的长度是多少 题解:把所有t建ac自动机,把s在ac自动机上匹配.保存每个模式串在s中出现的位置.这里由于t两两不同最多只有xsqr ...
- BOM&DOM
BOM(浏览器对象模型) 1. location相关 . location.href 获取当前url . location.href="http://www.sogo.com" 跳 ...
- sharing-jdbc实现读写分离及分库分表
需求: 分库:按业务线business_id将不同业务线的订单存储在不同的数据库上: 分表:按user_id字段将不同用户的订单存储在不同的表上,为方便直接用非分片字段order_id查询,可使用基因 ...
- erlang大法好
可惜haxe不能生成erlang.不过没关系,s6k输入法的实际执行方案,现在由typescript改用haxe.cdt3的ts地位不变. 以后这个博客大部分内容都是跟haxe/typescript相 ...
- jq demo 点击弹窗,居中,可滚动,可拖动
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- react native 环境报错
按照react native中文网的文档安装 1.brew 管理软件 2.node 在终端启动工程后就报下面这个错误 这个错误是在RN在第一次配置环境启动一个工程的时候 ,在这过程中下载的缓存文件不完 ...
- ADV7482&TP2825开发之总结
ADV7482&TP2825开发之总结 这一两个月在项目里接触到了两个视频解码芯片,主要是使用了两颗芯片的CVBS(NTSC)解码功能.外接CVBS Video接入解码芯片,芯片8位并行输出端 ...
- 百度地图JSSDK使用小实例
代码示例 <html> <head> <meta http-equiv="Content-Type" content="text/html; ...
- 剑指Offer 1. 二维数组中的查找 (数组)
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...