请教一下关于 nonce 防重放

2023-11-09 09:21:09 +08:00
 matepi
有一点没想明白,如果针对客户端是 web 页面的情况,那么 nonce 的生成算法,就一般都是在 web 端的 js 代码中了。

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

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

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

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

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

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

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

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

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

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

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

如果是 GET ,那随便并行。
matepi
2023-11-09 10:00:29 +08:00
@tool2d 返回头的返回情况,如果一个正常用户,在前一个正常请求还没有完成、返回头还没有带回客户端的情况下,就并行进行第二次正常请求,这种情况怎么办呢?或是 ajax 异步请求提交并发交易、或是直接保留原页面以右键在新页面中打开的方式提交交易呢
matepi
2023-11-09 10:02:21 +08:00
@tool2d ……现在的需求就是要控制幂等交易(大开销查询)的正常用户但其做的模拟幂等交易。随便放行并不行啊……
potatowish
2023-11-09 10:07:31 +08:00
客户端前端从服务端获取 nonce ,不管是通过接口返回还是返回头的方式,有心人都能获取新的 nonce
LonnyWong
2023-11-09 10:08:01 +08:00
@matepi 简单的 UUID 就可以,按需求定制适用的方案。
zliea
2023-11-09 10:09:52 +08:00
防重放其实主要还是 timestamp ,nonce 只是加入随机,增加难度而已。
cylx3124
2023-11-09 10:24:10 +08:00
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