请教一下关于 nonce 防重放

182 天前
 matepi
有一点没想明白,如果针对客户端是 web 页面的情况,那么 nonce 的生成算法,就一般都是在 web 端的 js 代码中了。

这样相当于 nonce 的生成过程,仍然是对客户端暴露的,只要重放人有能力进行客户端 js 的分析与模拟运行,那不是 nonce 就失效了么?
2684 次点击
所在节点    程序员
31 条回复
LonnyWong
182 天前
防重放不是说防用户重复请求,一般是防别人在网络上抓到你的包,然后重放。
举个例子,你向 A 转账 10 元,并不是说你不能再向 A 转 10 元。防的是 A 把你的包抓了,不断地转 10 元。
error451
182 天前
一个 nonce 只能够请求一次,你抓到了 nonce 再一次请求是不可能成功的啊, 怎么可能进行重放攻击?
你是不是混淆了 nonce ? nonce 不是 token 啊 , 不需要任何算法, 你自己手输入一个随机字符串也可以啊。没有人会对 nonce 校验,单纯的放一个列表里就行了。
一个算法就做一件事情,nonce 就只防止重放攻击,其他的安全措施需要用其他的算法,别混淆。
jinliming2
182 天前
即便是 web 页面,nonce 也是服务端下发的哇?
matepi
182 天前
@LonnyWong 理解了。但这样也是假设在这个“别人”并没有对服务端客户端深度分析的情况下吧。如果这个“别人”是有心人,分析了这个 nonce 整体的交互和生成过程。那应该也是仍然可以实现重放的?

又,如果要防用户的重复请求呢?尤其是查询类,没有类似金额控制类的情况呢。
killerv
182 天前
有点记不太清楚了,nonce 应该是服务端发放的,随机的保证一段时间内不重复就行,这个只能用一次,客户端生成 nonce ,服务端也不认啊
matepi
182 天前
@jinliming2 这意思是,nonce 是随着用户前一次请求,由服务器端返回客户端的,并在下一次请求中再带上服务端么?我看的理解还以为是都是客户端完全随机生成 uuid 或者带点 timestamp 之类的客户端算法生成?

如果是服务器端生成,那对于分布式化的服务端,一是要搞个中心存储节点来存了吧?二是,这样会禁止掉在客户端开启多个 web 页面,并行操作的可能?
retNu1l
182 天前
nonce 随机生成的,没有啥算法,没有签名情况下你随便改个字母都大概率命中不了重复校验。另外一般会对 once 同请求参数一起签名一下,增加逆向客户端及抓包篡改难度。
tool2d
182 天前
一般都是服务器返回的,你访问一下这个:

https://acme-v02.api.letsencrypt.org/acme/new-nonce

返回的头有 replay-nonce ,每次都会变,正常情况下客户端是无法生成的。

那些能生成的,都是野路子。
LonnyWong
182 天前
@matepi nonce 是完全随机的,一次性的,知道怎么生成也没用。你说的别人分析交互过程,不是防重放,是防假冒,要用其他手段来解决。

防重复请求,一般在请求前生成一个唯一的 ID ,后台要根据这个 ID 去重,前端要确保同一个请求的 ID 相同且全局唯一。
tool2d
182 天前
单纯客户端生成的,基于 timestamp 的签名,那种叫 Signature-Algorithm: HMACSHA256

我尝试过想破解,但是是一个 APP ,并不是 web js 代码,难度就挺大的。
matepi
182 天前
@retNu1l 这个签名如果是客户端做的,不是一样会能被搞掉的么?尤其 web 页面情况,js 代码都很好模拟的情况下
matepi
182 天前
@LonnyWong “一般在请求前生成一个唯一的 ID ”这个何时、何侧、以何种算法生成的呢?按我之前理解是客户端,现在听大家的意思的理解,应该是在前一次请求、由服务器端、按服务器端内的算法生成的?

“前端要确保同一个请求的 ID 相同且全局唯一。”我的理解,客户端前端只是把服务器端前一次下发的内容,在本次再带上服务器端的简单逻辑?客户端前端应该没有啥确保保证的能力吧。

但如果是“在前一次请求、由服务器端、按服务器端内的算法生成的”;“并在本次再带上服务器”的逻辑的话,似乎这个逻辑就会限制了用户开多个 web 页面并行做请求的能力?
vultr
182 天前
@matepi 8 楼 @tool2d 说的才是对的,nonce 得服务器返回才是安全的。
tool2d
182 天前
@matepi "似乎这个逻辑就会限制了用户开多个 web 页面并行做请求的能力?"

前端有个幂等属性,关键 POST 操作肯定不能并行请求。

如果是 GET ,那随便并行。
matepi
182 天前
@tool2d 返回头的返回情况,如果一个正常用户,在前一个正常请求还没有完成、返回头还没有带回客户端的情况下,就并行进行第二次正常请求,这种情况怎么办呢?或是 ajax 异步请求提交并发交易、或是直接保留原页面以右键在新页面中打开的方式提交交易呢
matepi
182 天前
@tool2d ……现在的需求就是要控制幂等交易(大开销查询)的正常用户但其做的模拟幂等交易。随便放行并不行啊……
potatowish
182 天前
客户端前端从服务端获取 nonce ,不管是通过接口返回还是返回头的方式,有心人都能获取新的 nonce
LonnyWong
182 天前
@matepi 简单的 UUID 就可以,按需求定制适用的方案。
zliea
182 天前
防重放其实主要还是 timestamp ,nonce 只是加入随机,增加难度而已。
cylx3124
182 天前
nonce 只是前后端签名验证的一部分, 一般通过 nonce + 时间戳 + 验签, 可以做到反爬虫和防止针对同一请求的重放。

nonce + 时间戳 + 验签的方式, 只能增加伪造请求的难度, 不能完全杜绝伪造请求。因为不管是浏览器还是 app 端, nonce 获取和验签代码都是在客户端本地运行的, 有能力的人一定能破解你的 nonce 和 验签算法。

B 站 app 就是典型的例子 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/misc/sign/APP.md

只有在后端做好风控、参数和业务逻辑的各种校验,才能真正做到接口的安全(服务器被攻击除外)。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/990102

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX