.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}\r\n", 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
}

 

posted @ 2018-05-20 10:13  随便取个名字算了  阅读(2195)  评论(0编辑  收藏  举报