using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Xml;

namespace a.utils
{
    /// <summary>
    /// 能处理请求报文和响应报文
    /// </summary>
    public class RequestHandlerB
    {

        /// <summary>
        /// 原始内容
        /// </summary>
        protected string content;


        public RequestHandlerB()
        {
            parameters = new Hashtable();

           // this.httpContext = httpContext;
        }

        public RequestHandlerB(HttpContext httpContext)
        {
            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;

        protected HttpContext httpContext;

        /// <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) != 0)
                {
                    sb.Append(k + "=" + Utils.UrlEncode(v, getCharset()) + "&");
                }
            }

            //去掉最后一个&
            if (sb.Length > 0)
            {
                sb.Remove(sb.Length - 1, 1);
            }

            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) != 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);

            //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);
            }
        }

        public void doSend()
        {
            this.httpContext.Response.Redirect(this.getRequestURL());
        }

        /// <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";
        }

        /// <summary>
        /// 设置页面提交的请求参数
        /// </summary>
        /// <param name="paramNames">参数名</param>
        public void setReqParameters(string[] paramNames) {
            this.parameters.Clear();
            foreach (string pName in paramNames) {
                string reqVal = this.httpContext.Request[pName];
                if (String.IsNullOrEmpty(reqVal)) {
                    continue;
                }
                this.parameters.Add(pName, reqVal);
            }
        }

        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) != 0
                    && "sign".CompareTo(k) != 0 && "key".CompareTo(k) != 0)
                {
                    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) != 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();

            //debug信息
            this.setDebugInfo(sb.ToString() + " => sign:" + sign);
            return getParameter("sign").Equals(sign);
        }


    }
}

--

 

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

基于XML 文档根节点名称为 "xml",   签名参数名为 "sign" .

 

"<xml> 

<a>11111</a>

<sign>11111</sign>

   </xml>"

 

签名用

utils.RequestHandlerB rhNotify = new utils.RequestHandlerB();
                    
                     
//设置报文参数
 

rhNotify.setParameter("return_code", return_code);
rhNotify.setParameter("return_msg", return_msg);


rhNotify.setKey(agentKeyModel.agent_key);
//设置代理KEY rhNotify.createSign(); //签名 string notifyToClientSign = rhNotify.getParameter("sign"); string notifyXML = rhNotify.parseXML();

 

 

验签

utils.RequestHandlerB rhValidSign = new utils.RequestHandlerB();
                        rhValidSign.setContent(content);//设置XML
                        rhValidSign.setKey(wxMchModel.key);//设置代理KEY

                        bool bValidSign = rhValidSign.isTenpaySign();
                        //验证签名
                        if (bValidSign)
                        {
                            scP.AppendLine("验证签名:OK");
                        }
                        else
                        {
                            scP.AppendLine("验证签名:FAIL");
                        }

 

 

--

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄