Nonce 是什么?这个“只用一次的数字”,撑起了半个互联网的安全
你一定见过这个词:Nonce。
挖矿的时候,矿工在疯狂地试 nonce。写 CSP 的时候,后端每次响应都要生成一个 nonce。调 OAuth 的时候,请求参数里又冒出一个 nonce。
同一个词,出现在完全不同的场景里。
它到底是什么?
先记一句话
Nonce = Number used once = 只使用一次的数字/随机值。
它的核心作用只有一个:让某次请求、交易或操作具有唯一性和新鲜性,从而防止重放攻击、重复提交或预测。
你可以把它理解成一张一次性凭证——用过就作废,别人捡到了也没用。
它有什么特点?
- 一次性:理想情况下,用完就失效
- 不可预测:安全场景里通常要求随机,不能被攻击者猜到
- 有时效:很多 nonce 会设置过期时间
- 可验证:服务器能检查它是否合法、是否已经用过
记住这四点,你就能判断一个东西是不是 nonce,或者它算不算合格的 nonce。
它在哪些地方出现?
1. 登录 / API 防重放
这是最经典的用法。
流程是这样的:服务器先给客户端发一个 nonce,客户端请求的时候带上它。服务器验证这个 nonce 没用过、没过期,然后立刻作废。攻击者就算截获了这个请求,也没法再重放一次——因为 nonce 已经失效了。
一句话:nonce 是“一次性门票”,检票之后作废,没法二次入场。
2. 区块链
区块链里 nonce 有两种截然不同的用法。
比特币 PoW:区块头里有一个 nonce。矿工不断修改这个值,计算哈希,直到满足难度目标。这个 nonce 是“试出来的”,可能试了几亿次才成功。
以太坊交易 nonce:每个账户维护一个交易计数器,从 0 开始递增。这个 nonce 保证交易顺序,防止重放。它不是随机数,是一个严格的递增值。
同一个词,一个代表“疯狂试错”,一个代表“严格计数”。这就是 nonce 的灵活性——只要能保证唯一性和新鲜性,具体形式无所谓。
3. HTTP / Web 安全
CSP nonce:服务器每次响应都生成一个随机 nonce,同时放在 CSP 响应头和 <script nonce="..."> 标签里。浏览器只执行 nonce 匹配的内联脚本,其他内联脚本一律拒绝。这是防 XSS 的一把利器。
OAuth / OpenID Connect:授权请求里带上 nonce,IdP 在 ID Token 里原样返回。客户端验证 nonce 是否一致——如果不一致,说明这个 ID Token 可能是被重放的。
4. WordPress
WordPress 的 nonce 有点特殊。
它其实不是严格的“只用一次”,而是一个带时效、绑定用户和动作的安全令牌。主要用来防 CSRF。
所以严格来说,WordPress 的 nonce 是一个“安全令牌”,只是借用了 nonce 这个名字。这也提醒我们:同一个术语,在不同系统里的实现可能完全不一样。看名字不如看行为。
它和相似概念的区别
很多人会把 nonce 和这几个东西搞混:
| 概念 | 特点 | 和 nonce 的区别 |
|---|---|---|
| Salt | 哈希加盐,每个密码不同 | 不一定是一次性的 |
| IV | 加密初始化向量,通常要求唯一 | 不一定保密,也不一定只用一次 |
| Token | 可能是长期有效的凭证 | nonce 更强调一次性 / 新鲜性 |
核心区别:nonce 的灵魂是“一次性”。Salt 和 IV 只是要求“唯一”,但可以长期复用。Token 就更不用说了,可能有效期好几天。
一句话总结
Nonce 就是一个只使用一次的值,用来保证操作唯一、防止重放。
在区块链里,它可能是矿工试出来的数,也可能是交易计数器。在 Web 安全里,它通常是随机令牌。在 WordPress 里,它甚至不严格“只用一次”。
形式千变万化,核心逻辑只有一个:用一次就作废,让重放攻击无处下手。
下次再看到 nonce,别被它的各种形态绕晕。记住四个字:一次性。
