签名来保证ASP.NET MVC OR WEBAPI的接口安全
当我们开发一款App的时候,App需要跟后台服务进行通信获取或者提交数据。如果我们没有完善的安全机制则很容易被别用心的人伪造请求而篡改数据。
所以我们需要使用某种安全机制来保证请求的合法。现在最常用的办法是给每个http请求添加一个签名,服务端来验证签名的合法性,如果签名合法则执行响应的操作,如果签名非法则直接拒绝请求。
签名算法
签名算法一般都使用Hash散列算法,常用的有MD5,SHA系列算法。这些算法可以根据不同的输入,计算出不同的结果,而且碰撞的概率很低。
签名算法跟加密算法不是一回事。很多同学都会说使用MD5加密一下,其实这是错误的。签名算法不能恢复原来的数据,因为它本身并不包含原来数据的信息。
而加密方法不同,加密方法是可以根据加密结果重新推算出原来的数据的。
HMAC SHA作为一种更加安全的签名算法,使用一个Key来影响签名的结果。这样同样的输入配合不同的Key可以得出不同的签名,更加安全。
public static string HmacSHA256(string secretKey,string plain){var keyBytes = Encoding.UTF8.GetBytes(secretKey);var plainBytes = Encoding.UTF8.GetBytes(plain);using (var hmacsha256 = new HMACSHA256(keyBytes)){var sb = new StringBuilder();var hashValue = hmacsha256.ComputeHash(plainBytes);foreach (byte x in hashValue){sb.Append(String.Format("{0:x2}", x));}return sb.ToString();}}
签名的参数
有了签名算法,那么我们签名的内容哪里来呢?
一般我们使用http请求的queryString然后加上时间戳还有随机数来作为签名的参数。
public static string MakeSignPlain(SortedDictionary<string,string> queryString,string time,string random ){var sb = new StringBuilder();foreach (var keyValue in queryString){sb.AppendFormat("{0}={1}&", keyValue.Key, keyValue.Value);}if (sb.Length>1){sb.Remove(sb.Length - 1, 1);}sb.Append(time);sb.Append(random);return sb.ToString().ToUpper();}
验证签名
验证签名就是简单的比较服务端生产的签名跟客户端生产的签名是否一直。
要注意的一点是最好验证下时间戳,跟服务端时间比较前后不能相差5分钟。这也是一个简单的防Replay Attack的手段。
public static bool Valid(string requestSign,string signPlain,string time, string secretKey){if (string.IsNullOrEmpty(time)||string.IsNullOrEmpty(requestSign)||string.IsNullOrEmpty(signPlain)){return false;}//is in rangevar now = DateTime.Now;long requestTime =0;if (long.TryParse(time,out requestTime)){var max = now.AddMinutes(5).ToString("yyyyMMddHHmmss");var min = now.AddMinutes(-5).ToString("yyyyMMddHHmmss");if (!(long.Parse(max) >= requestTime && long.Parse(min) <= requestTime)){return false;}}else{return false;}//hashmacvar sign = Encryption.HmacSHA256(secretKey, signPlain);return requestSign.Equals(sign, StringComparison.CurrentCultureIgnoreCase);}
ApiController基类
有了上面这些铺垫我们就可以在基类完成签名的验证了。客户端需要把上面提到的时间戳,随机数,签名和客户端的ID放入http请求的headers里面。
我们在基类的OnActionExecuting里取出这些数据组合成签名的参数,然后根据客户端ID获取签名的Key,然后使用同样的签名算法计算签名。并且比较客户端的签名跟服务端的签名是否一致。
这里就不演示了。
预防Replay Attack
预防重放攻击主要有两点:
- 校验时间戳的范围
时间戳跟服务器时间相差在一个合理的范围内视为合法。 - 缓存签名
每次请求都去判断下签名是否出现过。如果出现过则视为非法请求。
因为有时间戳跟随机数的存在,所以理论上每次请求的签名是不可能重复的。
客户端调用
这里演示一下C#签名并且调用http接口的代码
[TestMethod()]public void GetUserTest(){string url = "http://localhost:8090/api/test/GetUser";string userId = "A39891D4-6CEF-4538-A562-3A422CA9C17A";string appId = "100001";string secretKey = "M/vkPOWXgBa7GnRd73t7j+jsKfbZtb+f";string rumdon = Guid.NewGuid().ToString();string time = DateTime.Now.ToString("yyyyMMddHHmmss");//make signture plain textvar sortDict = new SortedDictionary<string, string>(){{"userId",userId }};var signPlain = new StringBuilder();foreach (var keyValue in sortDict){signPlain.AppendFormat("{0}={1}&", keyValue.Key, keyValue.Value);}if (signPlain.Length > 1){//remove last &signPlain.Remove(signPlain.Length - 1, 1);}signPlain.Append(time);signPlain.Append(random);Console.WriteLine("sign plain:{0}", signPlain.ToString().ToUpper());//make signvar sign = Encryption.HmacSHA256(secretKey, signPlain.ToString().ToUpper());Console.WriteLine("sign:{0}", sign);string requestUrl = string.Format("{0}?{1}={2}", url, "userId", userId);HttpWebRequest request = (HttpWebRequest)WebRequest.Create(requestUrl);request.Method = "GET";//add headersrequest.Headers.Add("time", time);request.Headers.Add("appId", appId);request.Headers.Add("random", random);request.Headers.Add("sign", sign);////start requesttry{using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()){var responseStream = response.GetResponseStream();if (responseStream != null){using (StreamReader reader = new StreamReader(responseStream)){var content = reader.ReadToEnd();Console.WriteLine(content);}}}}catch (WebException ex){using (HttpWebResponse response = (HttpWebResponse)ex.Response){var responseStream = response.GetResponseStream();if (responseStream != null){using (StreamReader reader = new StreamReader(responseStream)){var content = reader.ReadToEnd();Console.WriteLine(content);}}}}}
签名来保证ASP.NET MVC OR WEBAPI的接口安全相关推荐
- 如何解决Asp.Net MVC和WebAPI的Controller名称不能相同的问题
如何解决Asp.Net MVC和WebAPI的Controller名称不能相同的问题 参考文章: (1)如何解决Asp.Net MVC和WebAPI的Controller名称不能相同的问题 (2)ht ...
- ASP.NET MVC (五、HttpClient接口解析)
目录 前言: 1.MVC项目创建 2.[GET]请求的API解析 3.[Post]请求[API]解析 前言: MVC对于已经跨域的接口进行解析是个比较容易的事情.况且在第四章节的时候已经通过Ajax进 ...
- 关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案
问题描述 当跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况. 重现方式 使用模板创建一个最简单的ASP.NET Web ...
- ASP.NET MVC WebAPI 资源整理
注:这是收集给公司同事学习的资料,入门级别的. 使用ASP.Net WebAPI构建REST服务(一)--简单的示例 http://blog.csdn.net/mengzhengjie/article ...
- ASP.NET MVC学习系列(一)-WebAPI初探
由于即将要接手的新项目计划用ASP.NET MVC3来开发,所以最近一段时间一直在看相关的书或文章.因为之前在大学里也曾学习过MVC2开发,也做过几个简单的MVC2的小型测试项目,不过在后来工作以后主 ...
- ASP.Net MVC开发基础学习笔记:五、区域、模板页与WebAPI初步
一.区域-麻雀虽小,五脏俱全的迷你MVC项目 1.1 Area的兴起 为了方便大规模网站中的管理大量文件,在ASP.NET MVC 2.0版本中引入了一个新概念-区域(Area). 在项目上右击创建新 ...
- ASP.Net MVC开发基础学习笔记(5):区域、模板页与WebAPI初步
http://blog.jobbole.com/85008/ ASP.Net MVC开发基础学习笔记(5):区域.模板页与WebAPI初步 2015/03/17 · IT技术 · .Net, Asp. ...
- 【转】一个ASP.NET MVC中ajax调用WebApi返回500 Internal Server Error的调错方法。
ASP.NET MVC 引入的WebApi自然且较好地满足了ajax的交互需求,但使用jQuery ajax调用WebApi返回500 Internal Server Error时却不太好查找错误.在 ...
- 【转】.net异步性能测试(包括ASP.NET MVC WebAPI异步方法)
很久没有写博客了,今年做的产品公司这两天刚刚开了发布会,稍微清闲下来,想想我们做的产品还有没有性能优化空间,于是想到了.Net的异步可以优化性能,但到底能够提升多大的比例呢?恰好有一个朋友正在做各种语 ...
最新文章
- C#动态加载DLL(转)
- Oracle10g 回收站及彻底删除table : drop table xx purge
- Spring Boot + GraphQL 才是 API 的未来!
- 在 2D 横向卷轴游戏里上下楼梯
- Paxos在Chubby中的应用
- 工作121:[““]进行变量赋值
- Android学习----发行版本
- 1562区别 洛达1552_洛达1562A与洛达1536u与杰里有哪些区别呢?
- 《SPSS统计分析与行业应用实战》之序言
- windows下Edge浏览器Google Chrome与Safari双向同步书签
- Python Excel xlsx,xls,csv 格式互转
- ubuntu 16.04软件源
- 课程设计题四:LED彩灯控制器设计
- GEO数据库学习一(简介 数据下载 芯片知识)
- 【实战技能】软件工程师与AI工程师的区别是什么?
- 2016程序员你该爆发洪荒之力了!八招教你成功
- 小米电视/盒子 访问群晖 需要打开 设置“SMB1”
- Rabbitmq面试题总结,非常详细,杜绝标题党,不详细你打我,下次不写博客了
- 搜狗浏览器和360浏览器css布局注意事项
- 为什么机房计算机外放没有声音,学校机房win7单机游戏打不开?
热门文章
- python matplotlib 绘制K线图(蜡烛图)
- 高质量软件中的7项自动化要求
- 手机计算机器的作用,小米手机自带的计算器简直绝了,这功能也太强大了吧!...
- 【盲信道估计】基于matlab的LMS盲信道估计QPSK仿真
- java visibility_[Java教程]display 与 visibility
- 13.6.3 程序案例:BLE低功耗蓝牙调试助手
- 近视200度能学计算机吗,近视200度能不能恢复 近视200度该怎么办
- verilog基础——always、initial
- ubuntu18.04安装Cosmos Scaffold遇到的问题及解决方案
- 新一代人工智能知识体系大全