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 ...
随机推荐
- 发布npm
前言 我们npm publish发布的时候,一定是本地文件发布到远程仓库,并且登录到http://registry.npmjs.org(即npm adduser或npmlogin)之后,才可以进行发布 ...
- Python 同一文件中,有unittest不执行“if __name__ == '__main__”,不生成HTMLTestRunner测试报告的解决方案
1.问题:Python中同一个.py文件中同时用unittest框架和HtmlReport框架后,HtmlReport不被执行. 2.为什么?其实不是HtmlReport不被执行,也不是HtmlRep ...
- 蓝桥杯 每周一练 第一周(3n+1问题)
[问题描述] 考虑如下的序列生成算法:从整数 n 开始,如果 n 是偶数,把它除以 2:如果 n 是奇数,把它乘 3 加1. 用新得到的值重复上述步骤,直到 n = 1 时停止.例如,n = 22 时 ...
- Guava:好用的java类库 学习小记
基础功能 google guava中定义的String操作 在google guava中为字符串操作提供了很大的便利,有老牌的判断字符串是否为空字符串或者为null,用指定字符填充字符串,以及拆分合并 ...
- Linux目录结构下部
第1章 linux目录结构 (linux必知必会的文件或目录) 1.1 在linux下面如何安装软件 yum install tree 1.2 linux无法上网了怎么办? [root@oldboye ...
- 世界上最好的Sed教程
这是一份世界上最好的sed教程,sed是unix系统下流编辑里的超人.最初我写这份说明是为了我的 第二本电子书,然而随后我决定把这份说明变成一本免费电子书预览的同时再次做为文章发布到这里. Sed说明 ...
- 异常处理:try - except 和 try finally。
异常处理:try-except语句 1) 此处:as reason为可选参数,reason是一个变量. 2) 使用try—except语句时,检测范围内出现错误,不会有红色的报错提 ...
- oracle 11g安装过程
1,工具:Oracle_win64_11gR2_database(64位oracle 11g数据库).iso安装文件,win10系统 2,右键,解压后,点击setup.exe,系统会检测本机的环境,如 ...
- JAVA8之Lambda表达式与方法引用表达式
一.Lambda表达式 基本语法: lambdaParameters->lambdaBody lambdaParameters传递参数,lambdaBody用于编写逻辑,lambda表达式会生成 ...
- element-ui Select 清空model,页面没有清空选中项的问题
业务场景: 在dialog 每次打开时, 选择应用程序要初始化为空. 最初的做法为: 监听dialog的show状态,当show为false时,设置selectApp为空这样写时,虽然selectAp ...