.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 ...
随机推荐
- IBM小机拆镜像换盘
1.硬盘告警信息 2.故障排查 查看错误日志 # errpt -aj C62E1EB7 查看hdisk0的信息,发现hdisk0属于rootvg # lspv 查看hdi ...
- HMC版本支持
Target Version Upgrade From Upgrade Instructions Updates Date Available End of Service Models supp ...
- iptable防火墙原理
iptable防火墙原理 简介 Linux 2.0 ipfs/firewalld Linux 2.2 ipchain/firewall Linux 2.4 iptables/netfilter (ip ...
- Linux系统,无法收到组播消息的问题
解决办法: 做以下3个修改 1. /etc/sysctl.conf 文件中的 net.ipv4.conf.all.rp_filter 设置成0 2. sysctl -w net.ipv4.conf.a ...
- java数据结构复习01
1.数组 package javaDataStruct.array01; public class MyArray { private int[] arr; // 表示有效数据的长度 private ...
- (转) MiniUI使用
来源于https://my.oschina.net/yunsy/blog/542597 1.MiniUI页签定位 <body> <input name = "bizType ...
- Codeforces 899 1-N两非空集合最小差 末尾最多9对数计算 pair/链表加优先队列最少次数清空
A /*Huyyt*/ #include<bits/stdc++.h> #define mem(a,b) memset(a,b,sizeof(a)) #define pb push_bac ...
- 【gin-vue-admin】 使用go和vue 快速搭建一个项目模板
gin-vue-admin gin+vue开源快速项目模板 项目地址:https://github.com/piexlmax/gin-vue-admin 增加了 micro-service-test分 ...
- Python之网路编程之死锁,递归锁,信号量,Event事件,线程Queue
一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统 ...
- linux 上搭建sftp服务
原文链接:https://www.cnblogs.com/yanduanduan/p/9046723.html sftp和ftp的区别 FTP是一种文件传输协议,一般是为了方便数据共享的.包括一个FT ...