https://www.cnblogs.com/mymelody/p/7325325.html

 

  以前总是通过timestamp来防止重放攻击,但是这样并不能保证每次请求都是一次性的。今天看到了一篇文章介绍的通过nonce(Number used once)来保证一次有效,感觉两者结合一下,就能达到一个非常好的效果了。

重放攻击是计算机世界黑客常用的攻击方式之一,所谓重放攻击就是攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程。

  首先要明确一个事情,重放攻击是二次请求,黑客通过抓包获取到了请求的HTTP报文,然后黑客自己编写了一个类似的HTTP请求,发送给服务器。也就是说服务器处理了两个请求,先处理了正常的HTTP请求,然后又处理了黑客发送的篡改过的HTTP请求。

基于timestamp的方案

  每次HTTP请求,都需要加上timestamp参数,然后把timestamp和其他参数一起进行数字签名。因为一次正常的HTTP请求,从发出到达服务器一般都不会超过60s,所以服务器收到HTTP请求之后,首先判断时间戳参数与当前时间相比较,是否超过了60s,如果超过了则认为是非法的请求。

假如黑客通过抓包得到了我们的请求url: http://koastal.site/index/Info?uid=ZX07&stime=1480862753&sign=80b886d71449cb33355d017893720666

1
2
$sign=md5($uid.$token.$stime);
// 服务器通过uid从数据库中可读出token

  

  一般情况下,黑客从抓包重放请求耗时远远超过了60s,所以此时请求中的stime参数已经失效了。 
如果黑客修改stime参数为当前的时间戳,则sign参数对应的数字签名就会失效,因为黑客不知道token值,没有办法生成新的数字签名。

但这种方式的漏洞也是显而易见的,如果在60s之后进行重放攻击,那就没办法了,所以这种方式不能保证请求仅一次有效。

基于nonce的方案

  nonce的意思是仅一次有效的随机字符串,要求每次请求时,该参数要保证不同,所以该参数一般与时间戳有关,我们这里为了方便起见,直接使用时间戳的16进制,实际使用时可以加上客户端的ip地址,mac地址等信息做个哈希之后,作为nonce参数。 
我们将每次请求的nonce参数存储到一个“集合”中,可以json格式存储到数据库或缓存中。 
每次处理HTTP请求时,首先判断该请求的nonce参数是否在该“集合”中,如果存在则认为是非法请求。

  假如黑客通过抓包得到了我们的请求url: http://koastal.site/index/Info?uid=ZX07&nonce=58442c21&sign=80b886d71449cb33355d017893720666

其中:

  

1
2
$sign=md5($uid.$token.$nonce);
// 服务器通过uid从数据库中可读出token

  

  nonce参数在首次请求时,已经被存储到了服务器上的“集合”中,再次发送请求会被识别并拒绝。 
  nonce参数作为数字签名的一部分,是无法篡改的,因为黑客不清楚token,所以不能生成新的sign。

  这种方式也有很大的问题,那就是存储nonce参数的“集合”会越来越大,验证nonce是否存在“集合”中的耗时会越来越长。我们不能让nonce“集合”无限大,所以需要定期清理该“集合”,但是一旦该“集合”被清理,我们就无法验证被清理了的nonce参数了。也就是说,假设该“集合”平均1天清理一次的话,我们抓取到的该url,虽然当时无法进行重放攻击,但是我们还是可以每隔一天进行一次重放攻击的。而且存储24小时内,所有请求的“nonce”参数,也是一笔不小的开销。

  

基于timestamp和nonce的方案

那我们如果同时使用timestamp和nonce参数呢? 
nonce的一次性可以解决timestamp参数60s的问题,timestamp可以解决nonce参数“集合”越来越大的问题。

我们在timestamp方案的基础上,加上nonce参数,因为timstamp参数对于超过60s的请求,都认为非法请求,所以我们只需要存储60s的nonce参数的“集合”即可。

假如黑客通过抓包得到了我们的请求url: http://koastal.site/index/Info?uid=ZX07&stime=1480862753&nonce=58442c21&sign=80b886d71449cb33355d017893720666

其中:

1
2
$sign=md5($uid.$token.$stime.$nonce);
// 服务器通过uid从数据库中可读出token

  

  如果在60s内,重放该HTTP请求,因为nonce参数已经在首次请求的时候被记录在服务器的nonce参数“集合”中,所以会被判断为非法请求。超过60s之后,stime参数就会失效,此时因为黑客不清楚token的值,所以无法重新生成签名。

综上,我们认为一次正常的HTTP请求发送不会超过60s,在60s之内的重放攻击可以由nonce参数保证,超过60s的重放攻击可以由stime参数保证。

因为nonce参数只会在60s之内起作用,所以只需要保存60s之内的nonce参数即可。

我们并不一定要每个60s去清理该nonce参数的集合,只需要在新的nonce到来时,判断nonce集合最后一次修改时间,超过60s的话,就清空该集合,存放新的nonce参数集合。其实nonce参数集合可以存放的时间更久一些,但是最少是60s。

验证流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//判断stime参数是否有效
if$now $stime > 60){
    die("请求超时");
}
//判断nonce参数是否在“集合”已存在
if( in_array($nonce,$nonceArray) ){
    die("请求仅一次有效");
}
//验证数字签名   
if $sign != md5($uid.$token.$stime.$nonce) ){
    die("数字签名验证失败");
}
//判断是否需要清理nonce集合
if$now $nonceArray->lastModifyTime > 60 ){
    $nonceArray = null;
}
//记录本次请求的nonce参数
$nonceArray.push($nonce);
 
 
//开始处理合法的请求

  

【转载】基于timestamp和nonce的防重放攻击的更多相关文章

  1. 基于timestamp和nonce的防重放攻击

    以前总是通过timestamp来防止重放攻击,但是这样并不能保证每次请求都是一次性的.今天看到了一篇文章介绍的通过nonce(Number used once)来保证一次有效,感觉两者结合一下,就能达 ...

  2. 基于timestamp和nonce的防止重放攻击方案

    参考:http://blog.csdn.net/koastal/article/details/53456696

  3. timestamp 与 nonce 防止重放攻击

    重放攻击是计算机世界黑客常用的攻击方式之一,所谓重放攻击就是攻击者发送一个目的主机已接收过的包,来达到欺骗系统的目的,主要用于身份认证过程. 首先要明确一个事情,重放攻击是二次请求,黑客通过抓包获取到 ...

  4. Spring Boot如何设计防篡改、防重放攻击接口

    Spring Boot 防篡改.防重放攻击 本示例要内容 请求参数防止篡改攻击 基于timestamp方案,防止重放攻击 使用swagger接口文档自动生成 API接口设计 API接口由于需要供第三方 ...

  5. API设计中防重放攻击

    HTTPS数据加密是否可以防止重放攻击? 否,加密可以有效防止明文数据被监听,但是却防止不了重放攻击. 防重放机制 我们在设计接口的时候,最怕一个接口被用户截取用于重放攻击.重放攻击是什么呢?就是把你 ...

  6. 基于DES算法加密的防撞库密码系统项目总结

    项目内容:基于DES算法加密的防撞库密码系统 小组名:zqhzkzkj 目标:1.对用户输入的8位字符进行DES加密,要求用户输入8位密钥 2.对于不同的网站,不同的用户名生成不同的密码 小组成员:周 ...

  7. 基于PHP给大家讲解防刷票的一些技巧

    刷票行为,一直以来都是个难题,无法从根本上防止. 但是我们可以尽量减少刷票的伤害,比如:通过人为增加的逻辑限制. 基于 PHP,下面介绍防刷票的一些技巧: 1.使用CURL进行信息伪造 $ch = c ...

  8. 转载 基于Selenium WebDriver的Web应用自动化测试

    转载原地址:  https://www.ibm.com/developerworks/cn/web/1306_chenlei_webdriver/ 对于 Web 应用,软件测试人员在日常的测试工作中, ...

  9. [转载] 基于zookeeper、连接池、Failover/LoadBalance等改造Thrift 服务化

    转载自http://blog.csdn.net/zhu_tianwei/article/details/44115667 http://blog.csdn.net/column/details/sli ...

  10. [转载] 基于Redis实现分布式消息队列

    转载自http://www.linuxidc.com/Linux/2015-05/117661.htm 1.为什么需要消息队列?当系统中出现“生产“和“消费“的速度或稳定性等因素不一致的时候,就需要消 ...

随机推荐

  1. OOP的核心思想

    1. 封装 既是信息封装,把一些信息进行封装成对象,只保留部分接口和方法与外部联系,能有效避免程序间相互依赖,实现代码模块间松藕合 : 2. 继承 子类自动继承父类的属性和方法,继承实现了代码的重用性 ...

  2. kotlin更多语言结构——>操作符重载

    Kotlin允许我们为自己的类型提供预定义的一组操作符的实现.这些操作符具有固定的符号表示(如 + 或 *) 和固定的优先级.为实现这样的操作符,我们为相应的类型(即二元操作符左侧的类型和一元操作符的 ...

  3. npm install报错 Error: EACCES: permission denied

    报错内容 Unable to save binary /root/packageadmin/spring-boot-admin-2.1.6/spring-boot-admin-server-ui/no ...

  4. Nuxt.js 应用中的 app:resolve 事件钩子详解

    title: Nuxt.js 应用中的 app:resolve 事件钩子详解 date: 2024/10/17 updated: 2024/10/17 author: cmdragon excerpt ...

  5. 华为云-容器引擎CCE-基本概念

    云容器引擎(Cloud Container Engine,简称CCE)提供高度可扩展的.高性能的企业级Kubernetes集群,支持运行Docker容器.借助云容器引擎,您可以在华为云上轻松部署.管理 ...

  6. style="word-break: break-all;" 用于 对应 td 文本内容过长自适应换行适用

    style="word-break: break-all;" 用于 对应 td 文本内容过长自适应换行适用 <td style="word-break: break ...

  7. JavaScript String 对象-常用知识点

    JavaScript String 对象-常用知识点 对象用于处理文本(字符串). 对象创建方法: new String(). String 对象属性 属性 描述 constructor 对创建该对象 ...

  8. 用Python创建一个简单的Web服务器

    基本思路: 在浏览器地址栏通过输入本机地址:http://127.0.0.1:8000 能够访问我们自己创建的Web服务器,并且给浏览器返回一句Hello World 代码实现: 1 import s ...

  9. DearPyGui学习

    1.所有DPG应用程序必须做3件事: 创建和销毁上下文 (create_context) 创建和显示视区 (create_viewport.show_viewport) 设置和启动DearPyGui ...

  10. Python爬虫之数据解析

    1.Request库 HTTP测试工具:http://httpbin.org,以下的示例会以此为URL 属于第三方库,需要手动安装 pip install requests 基本用法 import r ...