Python 如何防止重放攻击?
技术百科
冷漠man
发布时间:2026-01-20
浏览: 次 Python防止重放攻击需同时满足唯一性、时效性、不可复用性:①加时间戳并校验±30秒窗口;②用UUID nonce+Redis缓存防重复;③对方法、路径、时间戳、nonce、排序参数及原始请求体哈希做HMAC-SHA256签名;④强制HTTPS传输。
Python 防止重放攻击的核心是确保每个请求具备唯一性、时效性和不可复用性。关键不在于加密本身,而在于对请求内容增加动态签名和时间约束。
添加时间戳与有效期校验
在请求中嵌入当前时间戳(如 Unix 时间秒数或毫秒),服务端收到后检查是否落在允许的时间窗口内(例如 ±30 秒)。超出即拒绝,避免旧请求被重复提交。
- 客户端生成请求时:
timestamp = int(time.time()) - 服务端验证时:
if abs(timestamp - time.time()) > 30: raise ValueError("Request expired") - 注意:客户端和服务端系统时间需大致同步,生产环境建议使用 NTP 校时
使用一次性随机数(nonce)
每次请求携带一个服务端未见过的随机字符串(如 UUID4),服务端缓存已使用的 nonce(推荐 Redis + 过期时间),重复出现即视为重放。
- 客户端生成:
nonce = str(uuid.uuid4()) - 服务端存储并设置过期:
redis.setex(f"nonce:{nonce}", 60, "1")(60 秒后自动清理) - 若
redis.get(f"nonce:{nonce}")存在,说明该 nonce 已用过,直接拦截
对请求参数做带密钥的签名(HMAC)
将请求方法、路径、时间戳、nonce 和排序后的参数拼接后,用服务端与客户端共享的密钥生成 HMAC-SHA256 签名,作为请求头(如 X-Signature)发送。服务端用相同逻辑重新计算比对。
- 签名原文示例:
f"GET|/api/user|{timestamp}|{nonce}|id=123&name=test" - 生成签名:
hmac.new(key, msg.encode(), hashlib.sha256).hexdigest() - 服务端必须按完全相同的规则拼接和签名,否则校验失败
- 密钥绝不暴露在客户端代码或日志中,建议通过环境变量或密钥管理服务加载
结合 HTTPS 与请求体完整性
即使有签名,也必须强制使用 HTTPS,防止中间人篡改或窃取签名参数。同时,对 POST/PUT 请求体(如 JSON)参与签名计算,避免攻击者仅修改 body 绕过校验。
- 读取原始请求体:
body = request.get_data() # Flask;或 Django 中用 request.body - 将
body的 SHA256 哈希值纳入签名原文,或直接将规范化的 JSON 字符串参与拼接 - 避免使用
request.json(可能触发解析副作用),优先用原始字节流保证一致性

# ai
# 见过
# python
# 客户端
# 复用
# 用过
# mac
# redis
# https
# js
# json
# go
# 环境变量
# if
# int
# 字节
# 字符串
# red
# 落在
# unix
# django
# 服务端
# flask
# 完全相同
# 随机数
# timestamp
# raise
# 重放
# 添加时间
相关栏目:
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
AI推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
SEO优化<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
技术百科<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
谷歌推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
百度推广<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
网络营销<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
案例网站<?muma echo $count; ?>
】
<?muma
$count = M('archives')->where(['typeid'=>$field['id']])->count();
?>
【
精选文章<?muma echo $count; ?>
】
相关推荐
- Laravel 查询 JSON 列:高效筛选包含数
- Win11无法识别耳机怎么办_解决Win11插耳机
- Win11怎么更改盘符_Win11磁盘管理修改驱动
- VSC怎样在VSC中调试PHPAPI_接口调试技巧
- c++的STL算法库find怎么用 在容器中查找指
- 如何使用Golang实现微服务状态监控_Golan
- 如何使用Golang反射将map转换为struct
- Win10电脑怎么设置休眠快捷键_Windows1
- 如何使用Golang搭建Web开发环境_快速启动H
- Win11怎样安装搜狗输入法_Win11安装搜狗输
- c# 服务器GC和工作站GC的区别和设置
- 如何在Golang中解压文件_Golang com
- Win11怎么设置任务栏对齐方式_Windows1
- Go 中的 := 运算符:类型推导机制与使用边界详
- 短链接怎么用php递归还原_多层加密链接的处理法【
- Windows10怎么备份注册表_Windows1
- Win11怎么设置默认邮件客户端 Win11修改M
- php后缀怎么变mp4能播放_让php伪装mp4正
- Win11视频默认播放器怎么改_Win11关联第三
- c++的mutex和lock_guard如何使用
- Win10怎样卸载自带Edge_Win10卸载Ed
- Python技术债务管理_长期维护解析【教程】
- Win11怎么关闭搜索历史_Win11清除设备上的
- Win11任务栏怎么调到左边_Win11开始菜单居
- Python性能剖析高级教程_cProfileLi
- c++怎么实现高并发下的无锁队列_c++ std:
- Win11快速助手怎么用_Win11远程协助连接教
- TestNG的testng.xml配置文件怎么写
- MAC如何隐藏文件夹及文件_MAC终端命令隐藏与第
- Win11怎么设置触控板手势_Windows11三
- php增删改查需要哪些扩展_开启mysqli或pd
- Win11搜索不到蓝牙耳机怎么办 Win11蓝牙驱
- mac怎么安装字体_MAC添加第三方字体与字体册管
- 如何在Golang中捕获结构体方法错误_Golan
- Python网络异常模拟_测试说明【指导】
- mac怎么打开终端_MAC终端Terminal使用
- c++ std::future和std::prom
- Win10如何卸载预装Edge扩展_Win10卸载
- 如何使用Golang实现云原生应用弹性伸缩_自动应
- Windows10如何更改计算机工作组_Win10
- 如何在 Go 中正确反序列化多个同级 XML 元素
- php与c语言在嵌入式中有何区别_对比两者在硬件控
- 如何在Golang中编写异步函数测试_Golang
- Win11怎么设置默认浏览器Chrome_Wind
- Windows 11登录时提示“用户配置文件服务登
- Win11怎么设置开机密码_Windows11账户
- c# await 一个已经完成的Task会发生什么
- 如何在Golang中处理JSON字段缺失_Gola
- PHP主流架构如何做单元测试_工具与流程【详解】
- C#如何在一个XML文件中查找并替换文本内容

QQ客服