.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().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) == )
{
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 = ; i < count; i++)
{
int startIndex = i;
int index = -;
while (i < count)
{
char item = queryString[i];
if (item == '=')
{
if (index < )
{
index = i;
}
}
else if (item == '&')
{
break;
}
i++;
}
string key = null;
string value = null;
if (index >= )
{
key = queryString.Substring(startIndex, index - startIndex);
value = queryString.Substring(index + , (i - index) - );
}
else
{
key = queryString.Substring(startIndex, i - startIndex);
}
if (isEncoded)
{
result[MyUrlDeCode(key, encoding)] = MyUrlDeCode(value, encoding);
}
else
{
result[key] = value;
}
if ((i == (count - )) && (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 = ;
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 = ;//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
}
.net通用签名方法 webapi签名方法的更多相关文章
- 十二、.net core(.NET 6)添加通用的访问webapi的方法(包括HttpClient和HttpWebRequest)
开发通用的访问webapi方法. 在common工具文件夹下,新建一个类库项目:Wsk.Core.WebHelper,并引用Package包项目,然后新建一个类HttpClientHelper,用于使 ...
- openssl使用多种方法签名、自签名
1.自建CA 自建CA的机制:1.生成私钥2.创建证书请求,在创建证书请求过程中由于需要提供公钥,而公钥来源于私钥,所以也需要指定私钥来创建证书请求,而实际上这里提供私钥的作用就是提取其中的公钥,这一 ...
- 微信开发所需要的的方法(签名认证、数组转字符串方法、将xml字符串转换为数组、发送xml请求方法)
//将xml字符串转换为数组 public function xmlToArray($xml){ $array_data = json_decode(json_encode(simplexml_loa ...
- 记录下Webapi签名机制
首先,写这篇文章的原因是因为最近某一个项目中的接口被人为调用了,导致了数据库数据被串改.虽然是内部人无意点的,但还是引起了我的担忧,所有整理了下关于Webapi的相关签名机制. 一.我们在开发接口时, ...
- 详解 WebAPI 签名机制
首先,写这篇文章的原因是因为最近某一个项目中的接口被人为调用了,导致了数据库数据被串改.虽然是内部人无意点的,但还是引起了我的担忧,所有整理了下关于WebAPI的相关签名机制. 一.我们在开发接口时, ...
- CSharpGL(36)通用的非托管数组排序方法
CSharpGL(36)通用的非托管数组排序方法 如果OpenGL要渲染半透明物体,一个方法是根据顶点到窗口的距离排序,按照从远到近的顺序依次渲染.所以本篇介绍对 UnmanagedArray< ...
- WebApi Put方法出现MethodNotAllowed解决方法
WebApi Put方法提交数据的时候总提示MethodNotAllowed,在网上查了很多资料才发现是因为IIS安装了一项服务“WebDAV”,在IIS中把“WebDAV”前面的勾去掉,重新启动电脑 ...
- C#中DataTable与实体集合通用转换(使用扩展方法)
本案例提供了:把DataRow转换为单个实体.dataTable转换为List泛型支持时间格式转换. 下文的方法都是扩展方法.扩展方法要求写在静态类中,方法也要静态. 它必须在一个非嵌套.非泛型的静态 ...
- .NET与 java通用的3DES加密解密方法
C#代码 private void button1_Click(object sender, EventArgs e) { string jiami = textBox1.Text; textBox2 ...
随机推荐
- PHP 优化之php -fpm 进程
一,php-fpm的启动参数 1 2 3 4 5 6 7 8 9 10 11 12 13 #测试php-fpm配置 /usr/local/php/sbin/php-fpm -t /usr/local/ ...
- VMware主机使用无线上网
VMware主机使用无线上网,默认的NAT连接在ubuntu下上不了网,需要把网络适配器改成桥接模式.
- mac中登陆mysql忘记密码解决办法
1.打开终端,输入命令:cd /usr/local/mysql/bin 2.mysql -uroot -p,用这条命令登陆时报错信息: 报错:Enter password: ERROR 1045 (2 ...
- 关于 html button 点击刷新页面的问题
如果不想点击button 刷新页面的话,需要加个属性 type="button" 如下: <button class="layui-btn" type ...
- win2008 ad域控搭建
一.前言 1.1 AD 域服务 什么是目录(directory)呢? 日常生活中使用的电话薄内记录着亲朋好友的姓名.电话与地址等数据,它就是 telephone directory(电话目录):计算机 ...
- 8.django单独执行文件
import os import django # 导入django os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'noju.settings')d ...
- #419 Div2 Problem C Karen and Game (贪心 && 暴力)
题目链接:http://codeforces.com/contest/816/problem/C 题意 :给出一个 n*m 的变化后的矩阵,变化前矩阵的元素全是0,变化的规则是选择其中的一行或者一列将 ...
- 【转载】What is the difference between authorized_keys and known_hosts file for SSH?
The known_hosts file lets the client authenticate the server, to check that it isn't connecting to a ...
- 【技术分享:python 应用之二】解锁用 VSCode 写 python 的正确姿势
之前一直用 notepad++ 作为编辑器,偶然发现了 VScode 便被它的颜值吸引.用过之后发现它启动快速,插件丰富,下载安装后几乎不用怎么配置就可以直接使用,而且还支持 markdown.当然, ...
- Spring Boot教程(二十)开发Web应用(1)
静态资源访问 在我们开发Web应用的时候,需要引用大量的js.css.图片等静态资源. 默认配置 Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则: /s ...