C# 如何防止重放攻击(转载)
转载地址:http://www.cnblogs.com/similar/p/6776921.html
重放攻击
重放攻击是指黑客通过抓包的方式,得到客户端的请求数据及请求连接,重复的向服务器发送请求的行为。 比如你有一个 “购买” 的操作,当你点击购买按钮时,向服务器发送购买的请求。而这时黑客对你的请求进行了抓包,得到了你的传输数据。 因为你填写的都是真实有效的数据,是可以购买成功的,因此他不用做任何改变,直接把你的数据再往服务器提交一次就行了。这就导致了,你可能只想购买一个产品的,结果黑客重放攻击,你就购买了多次。如果是用户操作的话,肯定就会莫名奇妙:怎么购买了那么多同样的产品,我只买了一个啊? 所以,重放攻击的危害还是挺大的,特别是涉及到金钱交易时,因此防重放攻击在电商项目中是必不可少的。
解决方案
时间戳(tamp) + 数字签名(sign)。 也就是说每次发送请求时多传两个参数,分别为 tamp 和 sign。比如
原先请求为 http://127.0.0.1/api/buyproduct
修改之后为 http://127.0.0.1/api/buyproduct?tamp=1403149835&sign=945bf36r046bd84df2985ad625c9f92415eccd1w
数字签名的作用是为了确保请求的有效性。因为签名是经过加密的,只有客户端和服务器知道加密方式及Key,所以第三方模拟不了。我们通过对sign的验证来判断请求的有效性,如果sign验证失败则判定为无效的请求,反之有效。 但是数字签名并不能阻止重放攻击,因为黑客可以抓取你的tamp和sign(不需做任何修改),然后发送请求。这个时候就要对时间戳进行验证。
时间戳的作用是为了确保请求的时效性。我们将上一次请求的时间戳进行存储,在下一次请求时,将两次时间戳进行比对。如果此次请求的时间戳和上次的相同或小于上一次的时间戳,则判定此请求为过时请求,无效。因为正常情况下,第二次请求的时间肯定是比上一次的时间大的,不可能相等或小于。
有人会问,我直接用时间戳不就行了,为什么还要数字签名?因为黑客可能对请求进行抓包,然后修改时间戳为有效的时间戳值。我们的数字签名采用 tamp+key 进行组合加密,即使黑客修改了 tamp ,但是由于黑客不知道key,所以 sign 验证这步就成功的阻止了黑客的请求。
实例代码
加密方式采用 SHA1,SHA1加密方法进行了封装,写成了string的扩展方法。

/// <summary>
/// 数字签名
/// </summary>
/// <param name="tamp">时间戳(由客户端传入)</param>
/// <param name="key">Key</param>
/// <returns></returns>
private string Sign(string tamp, string key)
{
string txt = tamp + "|" + key; //在每个参数中间加了个 "|" ,增加复杂度
string sign = txt.GetSha1();
return sign;
}

验证方法, 客户端的加密方式和服务端是一样的,如果两者的加密结果不一致,则验证失败。 如果客户端是js,一定要对js做代码混淆,禁止右键等。因为我是用Session存储上一次请求的时间戳的,而Session是会过时的,当Session过时时黑客再进行攻击,就会得手,所以限制请求有效期为30秒。

/// <summary>
/// 检查请求是否有效,防重放
/// </summary>
/// <param name="tamp">时间戳(由客户端传入)</param>
/// <param name="key">Key</param>
/// <param name="sign">验签(由客户端传入)</param>
/// <returns></returns>
private bool CheckRequest(string tamp, string key, string sign)
{
//验签(比对客户端的加密结果和服务端的加密结果,如果不相等,则验签失败)
if (sign.ToUpper() != Sign(tamp, key).ToUpper()) return false; //得到当前时间戳
DateTime DateStart = new DateTime(1970, 1, 1, 8, 0, 0);
int nowTamp = Convert.ToInt32((DateTime.Now - DateStart).TotalSeconds);
if ((nowTamp - int.Parse(tamp)) > 30) return false; //因为Session可能过时,所以限定请求有效时间为30秒
//得到上一次的时间戳
string prevTamp = Session["tamp"] as string;
//判断是否为空,为空说明是第一次请求
if (!string.IsNullOrWhiteSpace(prevTamp))
{
if (int.Parse(tamp) > int.Parse(prevTamp))
{
Session["tamp"] = tamp;
return true;
}
else
{
return false;
}
}
else
{
Session["tamp"] = tamp;
return true;
}
}
C# 如何防止重放攻击(转载)的更多相关文章
- 全站 HTTPS 来了(转载)
转载:本文为腾讯Bugly原创文章. 最近大家在使用百度.谷歌或淘宝的时候,是不是注意浏览器左上角已经全部出现了一把绿色锁,这把锁表明该网站已经使用了 HTTPS 进行保护.仔细观察,会发现这些网站已 ...
- [转载] TLS协议分析 与 现代加密通信协议设计
https://blog.helong.info/blog/2015/09/06/tls-protocol-analysis-and-crypto-protocol-design/?from=time ...
- App架构经验总结(转载)
原文地址:http://www.iteye.com/news/31472 架构因人而异,不同的架构师大多会有不同的看法:架构也因项目而异,不同的项目需求不同,相应的架构也会不同.然而,有些东西还是通用 ...
- 银行手机APP安全评估报告【转载】
猫头鹰工作室 我不相信命运,但尊敬命运 主页 大数据 Kafka Spark Hbase Redis Flume ActiveMQ 渗透测试 方法论 Kali测试 APP安全 OWASP 脑图 Too ...
- 使用burpsuite进行重放攻击
原创博客,转载请注出处! 我的公众号,正在建设中,欢迎关注: 1.安装好burpsuite后打开程序,切换至proxy->intercipt,因为是重放攻击不用拦截数据包所以关闭intercep ...
- Crystal Clear Applied: The Seven Properties of Running an Agile Project (转载)
作者Alistair Cockburn, Crystal Clear的7个成功要素,写得挺好. 敏捷方法的关注点,大家可以参考,太激动所以转载了. 原文:http://www.informit.com ...
- RTP与RTCP协议介绍(转载)
RTSP发起/终结流媒体.RTP传输流媒体数据 .RTCP对RTP进行控制,同步.RTP中没有连接的概念,本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完 ...
- 《Walking the callstack(转载)》
本文转载自:https://www.codeproject.com/articles/11132/walking-the-callstack Download demo project with so ...
- [转载]MVVM模式原理分析及实践
没有找到很好的MVVM模式介绍文章,简单找了一篇,分享一下.MVVM实现了UI\UE设计师(Expression Blend 4设计界面)和软件工程师的合理分工,在SilverLight.WPF.Wi ...
随机推荐
- Nsis Sqlite Plugin
1.https://stackoverflow.com/questions/15346338/nsis-and-sqlite-integration 2.http://nsis.sourceforge ...
- Spring AsyncRestTemplate
类说明 AsyncRestTemplate 是 Spring中提供异步的客户端HTTP访问的核心类.与RestTemplate类相似,它提供了一些类似的方法,只不过返回类型不是具体的结果,而是List ...
- 使用Fiddler发送POST请求
使用Fiddler发送POST请求 在测试过程中,有时会遇到需要修改请求中带的参数,去验证权限的安全问题,但是一些post请求,我们在浏览器中不能直接修改他的参数,然后去提交验证. 而fiddler可 ...
- 网站连接数据库连接不上原因是ip地址与端口号格式不对
192.168.1.1:8080这样连接一直出错, 后来改为192.168.1.1,8080就可以了 原因是格式不对,把冒号给为逗号就可以了
- Ubuntu 16.04安装Git及GUI客户端
1.通过APT源安装Git命令行工具 这里不建议通过源码进行安装,增加复杂程度,且最新版本的Git在各个方面都会修复,不至于出现不能用的状态. sudo add-apt-repository ppa: ...
- Python3 enumerate() 函数
Python3 enumerate() 函数 Python3 内置函数 描述 enumerate() 函数用于将一个可遍历的数据对象(如列表.元组或字符串)组合为一个索引序列,同时列出数据和数据下标 ...
- sql批量修改字段内容的语句-SQL技巧
--update '表名' set 要修改字段名 = replace (要修改字段名,'被替换的特定字符','替换成的字符')--update tRecord set columnName = rep ...
- SQL时间格式化 转载备用~
Sel1 取值后格式化{0:d}小型:如2005-5-6{0:D}大型:如2005年5月6日{0:f}完整型 2 当前时间获取 DateTime.Now.ToShortDateString 3 取值中 ...
- Spring框架整合WEB解决配置文件加载多次的问题
1. 创建JavaWEB项目,引入Spring的开发包.编写具体的类和方法. * 环境搭建好后,启动服务器来测试项目,发送每访问一次都会加载一次配置文件,这样效率会非常非常慢!! 2. 解决上面的问题 ...
- 数据帮助类DBhelper的定义
数据库帮助类的使用DBhelperusing System;using System.Collections.Generic;using System.Text;using System.Data;u ...