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

基于timestamp和nonce的防止重放攻击方案以前总是通过 timestamp 来防止重放攻击 但是这样并不能保证每次请求都是一次性的 今天看到了一篇文章介绍的通过 nonce Numberusedon 来保证一次有效 感觉两者结合一下 就能达到一个非常好的效果了 重放攻击是计算机世界黑客常用的攻击方式之一 所谓重放攻击就是攻击者发送一个目的主机已接收过的包 来达到欺骗系统的目的 主要用于身份认证过程 首先要明确一个事情 重

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

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

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

基于timestamp的方案

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

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

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

基于nonce的方案

其中

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

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

基于timestamp和nonce的方案

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

其中

$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。
随机数集合可以根据业务场景采用定期清理或根据大小自动清理的方案,例如该接口每秒的请求数最高为1000,则60s内的请求数量最多为1500*60=90000,则我们在每次请求后检查集合大小是否超过90000,若超高该数量则清空。

验证流程

//判断stime参数是否有效 if( $now - $stime > 60){ die("请求超时"); } //判断nonce参数是否在“集合”已存在 if( in_array($nonce,$nonceArray) ){ die("请求仅一次有效"); } //验证数字签名  if ( $sign != md5($uid.$token.$stime.$nonce) ){ die("数字签名验证失败"); } /* if( $now - $nonceArray->lastModifyTime > 60 ){ $nonceArray = null; } $nonceArray.push($nonce); */ //处理随机数 $key = 'nonce'+$uid; if($redis->sismember($key,$nonce) === true){ die('拒绝重放攻击请求'); } if($redis->scard($key) > 90000){ $redis->del($key); } $redis->sadd($key,$nonce); //重放攻击检查完成

参考文章:

http://www.360doc.com/content/14/0116/16/834950_345740386.shtml

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/226411.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午10:58
下一篇 2026年3月16日 下午10:58


相关推荐

  • 关于爱未删减版高清_init not tainted

    关于爱未删减版高清_init not taintedhttp://blog.csdn.net/wangkaiblog/article/details/8741042http://blog.linux.org.tw/~jserv/archives/001954.html

    2022年8月11日
    9
  • RangeValidator控件[通俗易懂]

    RangeValidator控件[通俗易懂]控件用来:验证输入值是否在指定范围内aspxdiv>成绩:日期:

    2022年7月12日
    24
  • 如何在阿里云服务器Centos 7中部署定时签到python脚本

    如何在阿里云服务器Centos 7中部署定时签到python脚本

    2021年10月3日
    53
  • Linux基本操作命令 实验

    Linux基本操作命令 实验一、实验目的:1. 熟悉Linux基本命令。2. 熟悉Linux操作系统。二、实验环境:一台装有Linux的机器。三、实验内容:1.文件操作命令的使用。用vi编辑器新建一个testl文件输入thisistestl~!查看文件与目录ls进入Linux系统,输入ls-m按回车键执行。 一、实验目的:1. 熟悉Linux基本命令。2. 熟悉Linux操作系统。 二、实验环境:一台装有Linux的机器…

    2026年4月18日
    6
  • Centos 查看文件夹大小

    Centos 查看文件夹大小查看文件夹大小查询当前目录总大小可以使用 du sh 其中 s 代表统计汇总的意思 即只输出一个总和大小 含义命令查看指定目录的总大小 du sh 目录名称查看当前目录的总大小 du sh 查看当前目录 1 层深各文件夹大小 du hmax depth 1 查看当前目录 2 层深各文件夹大小 du hmax depth 2 查看文件大小含义命令以字节显示文件大小 ls ll 以 KB MB 显示文件大小 ls lh 当前目录

    2026年3月17日
    2
  • 往事再见!砥砺前行

    往事再见!砥砺前行4 个小时后我将离开深圳北上杭州 是的 我离职了 又一次换了城市 列维长跳 又一次上演 和大多数为求职和求偶或路过或移居的人们不同 我深深感受着每一座城市的厚重与轻浮 在所有这些地方 在定居者们看来 我又仅仅是另一个路过者 而已 不得不说 哈尔滨是一个神奇的地方 每一次列维长跳都和哈尔滨有关 我永远记得 2002 年的寒冷的冬天 那即便是对我这种超级抗冻的家伙也绝对是个考验 我在冰冻的松

    2026年3月16日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号