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. Java日期时间API系列17-----Jdk8中java.time包中的新的日期时间API类,java日期计算4,2个日期对比,获取相差年月日部分属性和相差总的天时分秒毫秒纳秒等

    通过Java日期时间API系列9-----Jdk8中java.time包中的新的日期时间API类的Period和Duration的区别 ,可以看出java8设计非常好,新增了Period和Durati ...

  2. less 是什么?为什么使用less?

    less 是css的预处理器,是动态语言,赋予了css动态的特性,如继承,变量,函数等,less可以执行在客户端和服务端: 为什么使用less a)less 的结构简单,便于扩展 b)实现多重继承 c ...

  3. 什么是变量污染? let、const、var的区别?

    变量污染就是全局变量滥用,造成报错,覆盖等问题:简单讲就是使用了相同的标识符声明了全局变量,var关键字声明相同的变量名会覆盖,let.const重复声明相同的变量名会直接报错: var 可以声明提升 ...

  4. element的图片上传预处理函数

    /** 图片格式和大小的控制 */ beforeAvatarUpload (file) { // 允许上传 jpg 和 png 格式的图片 const isJPG = file.type === &q ...

  5. Android复习(二)应用资源——>菜单

    菜单资源定义可通过 MenuInflater 进行扩充的应用菜单,包括选项菜单.上下文菜单和子菜单. 有关使用菜单的指南,请参阅菜单开发者指南. 文件位置: res/menu/filename.xml ...

  6. fastjson序列化导致prometheus返回监控数据格式错乱

    在springboot 中集成prometheus的监控时遇见问题. 因为项目里在StaticResourceConfig配置了fastjson 序列化,导致prometheus接口返回数据被转化为j ...

  7. Required request parameter ‘xxx‘ for method parameter type xxxx is not present 解决方式

    我在controller层传实体参数时加了@RequestParam,结果报Required request parameter 'pointlist' for method parameter ty ...

  8. 使用 Fluent Bit 实现云边统一可观测性

    本文基于 KubeSphere 可观测性与边缘计算负责人霍秉杰在北美 KubeCon 的 Co-located event Open Observability Day 闪电演讲的内容进行整理. 整理 ...

  9. thinkphp5 模型批量增加数据小记

    楼主最近在学习thinkphp5,真的没应广大使用教程所说:你最好就是没学过thinkphp3.2.要不然苦恼重重. 因为想将一些功能实现一次,故自己写了一个文件上传类. 可以实现单文件,多文件上传( ...

  10. Redis数据结构:List类型全面解析

    文章目录 一.List数据类型 1.1 简介 1.2 应用场景 1.3 底层结构 二.数据结构 2.1 压缩列表ZipList 2.2 双向链表LinkedList(后续已废弃) 2.3 快速链表Qu ...