• .net通用签名方法 webapi签名方法


    验证签名方法

    [HttpGet]
    public HttpResponseMessage LockRegister(string 参数1, int 参数2, string 参数3, string 参数4, int 参数5 ……)
    {
        bool signResult = SignHelper.CheckSign(new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().GetParameters(), this.ControllerContext.Request.RequestUri.Query);//验证签名方法
        return null;
    }

    返回参数签名

    public class ResultMsg
    {
        public virtual string sign
        {
            get
            {
                return SignHelper.Sign(this);
            }
        }
        public int code
        {
            get;
            set;
        }
        public string msg
        {
            get;
            set;
        }
    }
    public class LockRegisterResult : ResultMsg
    {
        public string SerialNumber { get; set; }
        public List<DataTable> ListTab { get; set; }
        public new string sign
        {
            get
            {
                return SignHelper.Sign(this, new string[] { "ListTab" });
            }
        }
    }

    实现:

    using System;
    using System.Collections.Generic;
    using System.Collections.Specialized;
    using System.IO;
    using System.Linq;
    using System.Net;
    using System.Security.Cryptography;
    using System.Text;
    using System.Web;
    
    
    /// <summary>
    /// 通用方法类
    /// </summary>
    public class SignHelper
    {
    
        private static string Key = "";
    
        /// <summary>
        /// 签名
        /// </summary>
        /// <typeparam name="T">泛型类</typeparam>
        /// <param name="t">传入this</param>
        /// <param name="ignorePropertys">忽略哪个属性不签名</param>
        /// <returns></returns>
        public static string Sign<T>(T t, string[] ignorePropertys = null)
        {
            Dictionary<string, string> dic = new Dictionary<string, string>();
            var propertys = t.GetType().GetProperties();
            foreach (var item in propertys)
            {
                if (item.Name.Equals("sign"))
                {
                    continue;// 避免无限循环
                }
                if (item.PropertyType.Namespace.ToLower().Equals("System.Collections.Generic".ToLower()))
                {
                    continue;
                }
    
                bool ignore = false;
    
                if (ignorePropertys != null)
                {
                    foreach (var ignoreProperty in ignorePropertys)
                    {
                        if (item.Name.Equals(ignoreProperty))
                        {
                            ignore = true;
                            break;
                        }
                    }
                }
                if (!ignore)
                {
                    var value = item.GetValue(t, null);
                    if (value != null && !string.IsNullOrEmpty(value.ToString()))
                    {
                        dic.Add(item.Name, value.ToString());
                    }
                }
            }
            return Sign(dic);
        }
    
        /// <summary>
        /// 签名
        /// </summary>
        /// <param name="dicParams">签名参数</param>
        /// <returns></returns>
        public static string Sign(Dictionary<string, string> dicParams)
        {
            //将字典中按ASCII码升序排序
            Dictionary<string, string> dicDestSign = new Dictionary<string, string>();
            dicDestSign = AsciiDictionary(dicParams);
            var sb = new StringBuilder();
            foreach (var sA in dicDestSign)//参数名ASCII码从小到大排序(字典序);
            {
                if (string.IsNullOrEmpty(sA.Value) || string.Compare(sA.Key, "sign", true) == 0)
                {
                    continue;// 参数中为签名的项,不参加计算//参数的值为空不参与签名;
                }
                string value = sA.Value.ToString();
    
                sb.Append(sA.Key).Append("=").Append(sA.Value).Append("&");
    
            }
            var string1 = sb.ToString();
            sb.Append(Key);//在stringA最后拼接上key=(API密钥的值)得到stringSignTemp字符串
            var stringSignTemp = sb.ToString();
            var sign = MD5(stringSignTemp, "UTF-8").ToUpper();//对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。 
            return sign;
        }
    
        /// <summary>
        /// MD5加密
        /// </summary>
        /// <param name="encypStr">需要md5加密的字符串</param>
        /// <param name="charset">编码</param>
        /// <returns>返回加密后的MD5字符串</returns>
        public static string MD5(string encypStr, string charset = "UTF-8")
        {
            string retStr = string.Empty;
            MD5CryptoServiceProvider m5 = new MD5CryptoServiceProvider();
    
            //创建md5对象
            byte[] inputBye;
            byte[] outputBye;
    
            //使用GB2312编码方式把字符串转化为字节数组.
            try
            {
                inputBye = Encoding.GetEncoding(charset).GetBytes(encypStr);
            }
            catch
            {
                inputBye = Encoding.GetEncoding("GB2312").GetBytes(encypStr);
            }
            outputBye = m5.ComputeHash(inputBye);
    
            retStr = BitConverter.ToString(outputBye);
            retStr = retStr.Replace("-", "").ToUpper();
            return retStr;
        }
    
        /// <summary>
        /// 将集合key以ascii码从小到大排序
        /// </summary>
        /// <param name="sArray">源数组</param>
        /// <returns>目标数组</returns>
        public static Dictionary<string, string> AsciiDictionary(Dictionary<string, string> sArray)
        {
            Dictionary<string, string> asciiDic = new Dictionary<string, string>();
            string[] arrKeys = sArray.Keys.ToArray();
            Array.Sort(arrKeys, string.CompareOrdinal);
            foreach (var key in arrKeys)
            {
                string value = sArray[key];
                asciiDic.Add(key, value);
            }
            return asciiDic;
        }
    
    
        #region 验证签名
    
        /// <summary>
        /// 验证签名
        /// </summary>
        /// <param name="parameters">当前方法参数数组</param>
        /// <param name="queryString">queryString</param>
        /// <returns></returns>
        public static bool CheckSign(System.Reflection.ParameterInfo[] parameters, string queryString)
        {
            System.IO.File.AppendAllText(AppDomain.CurrentDomain.BaseDirectory + "\调用日志.csv", string.Format("{0},{1:yyyy-MM-dd HH:mm}
    ", queryString, DateTime.Now));
            //return true;
            Dictionary<string, string> dic = new Dictionary<string, string>();
    
            NameValueCollection col = GetQueryString(queryString);
            foreach (var property in parameters)
            {
                var value = col[property.Name];
                //参数的值为空不参与签名;// 参数中为签名的项,不参加计算
                if (property.Name.Equals("sign") || string.IsNullOrEmpty(value))
                {
                    continue;
                }
                dic.Add(property.Name, value);
            }
            string signResult = Sign(dic);
            return col["sign"].ToString().Equals(signResult);
        }
    
    
        /// <summary>
        /// 将查询字符串解析转换为名值集合.
        /// </summary>
        /// <param name="queryString">queryString</param>
        /// <returns></returns>
        private static NameValueCollection GetQueryString(string queryString)
        {
            return GetQueryString(queryString, null, true);
        }
    
        /// <summary>
        /// 将查询字符串解析转换为名值集合.
        /// </summary>
        /// <param name="queryString"></param>
        /// <param name="encoding"></param>
        /// <param name="isEncoded"></param>
        /// <returns></returns>
        private static NameValueCollection GetQueryString(string queryString, Encoding encoding, bool isEncoded)
        {
            queryString = queryString.Replace("?", "");
            NameValueCollection result = new NameValueCollection(StringComparer.OrdinalIgnoreCase);
            if (!string.IsNullOrEmpty(queryString))
            {
                int count = queryString.Length;
                for (int i = 0; i < count; i++)
                {
                    int startIndex = i;
                    int index = -1;
                    while (i < count)
                    {
                        char item = queryString[i];
                        if (item == '=')
                        {
                            if (index < 0)
                            {
                                index = i;
                            }
                        }
                        else if (item == '&')
                        {
                            break;
                        }
                        i++;
                    }
                    string key = null;
                    string value = null;
                    if (index >= 0)
                    {
                        key = queryString.Substring(startIndex, index - startIndex);
                        value = queryString.Substring(index + 1, (i - index) - 1);
                    }
                    else
                    {
                        key = queryString.Substring(startIndex, i - startIndex);
                    }
                    if (isEncoded)
                    {
                        result[MyUrlDeCode(key, encoding)] = MyUrlDeCode(value, encoding);
                    }
                    else
                    {
                        result[key] = value;
                    }
                    if ((i == (count - 1)) && (queryString[i] == '&'))
                    {
                        result[key] = string.Empty;
                    }
                }
            }
            return result;
        }
    
        /// <summary>
        /// 解码URL.
        /// </summary>
        /// <param name="encoding">null为自动选择编码</param>
        /// <param name="str"></param>
        /// <returns></returns>
        private static string MyUrlDeCode(string str, Encoding encoding)
        {
            if (encoding == null)
            {
                Encoding utf8 = Encoding.UTF8;
                //首先用utf-8进行解码                     
                string code = HttpUtility.UrlDecode(str.ToUpper(), utf8);
                //将已经解码的字符再次进行编码.
                string encode = HttpUtility.UrlEncode(code, utf8).ToUpper();
                if (str == encode)
                    encoding = Encoding.UTF8;
                else
                    encoding = Encoding.GetEncoding("gb2312");
            }
            return HttpUtility.UrlDecode(str, encoding);
        }
    
        /// <summary>
        /// 创建http请求
        /// </summary>
        /// <param name="ClassName">方法名</param>
        /// <param name="sArray">参数</param>
        /// <returns></returns>
        public static string HttpPost(string ClassName, Dictionary<string, string> sArray)
        {
            var sb = new StringBuilder();
            int i = 0;
            foreach (var sA in sArray)
            {
                i++;
                string value = sA.Value.ToString();
                sb.Append(sA.Key).Append("=").Append(sA.Value);
                if (i != sArray.Count)
                    sb.Append("&");
            }
    
            string HttpUrl = string.Format("{0}{1}", ClassName, "?" + sb.ToString());
            Encoding encoding = Encoding.UTF8;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(HttpUrl);
            request.Method = "POST";
            request.Accept = "text/html, application/xhtml+xml, */*";
            request.Timeout = 10000;//10秒超时
            request.ContentType = "application/x-www-form-urlencoded";
            //如果内容在BODY请示,加入下面
            //byte[] buffer = encoding.GetBytes(body);
            //request.ContentLength = buffer.Length;
            //request.GetRequestStream().Write(buffer, 0, buffer.Length);
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
            {
                return reader.ReadToEnd();
            }
        }
    
        #endregion
    }
  • 相关阅读:
    随笔
    std::condition_variable(复习)
    随笔
    std::vector<std::vector<> >
    staitc_cast,const_cast....
    复制构造函数
    c++ 临时对象
    复制初始化和直接初始化
    随笔
    Fedora 安装oracle11g 之最简洁方式
  • 原文地址:https://www.cnblogs.com/linmilove/p/8289068.html
Copyright © 2020-2023  润新知