应用安全

握手防重放:Nonce、时间窗和会话绑定缺一不可

为连接请求和鉴权消息加入高熵 nonce、唯一会话 ID、双方身份、协议上下文与有限接受窗口,阻止旧签名再次开会话。

这类问题看似集中在一个 API 或参数上,真正决定可用性的却是状态归属、资源上限和失败后的恢复方式。 数字签名证明消息来自持钥者,却不证明消息是新的。挑战必须由验证方生成且一次性使用,签名内容还需绑定目标身份和操作类型。

安全评审要从资产、攻击者能力和信任边界出发,并在每次状态转换重新授权。输入校验、速率限制和审计只能互补,任何一个都不能替代权限判断。

先把实现决策说清楚

实现之前先列出不可违反的不变量,再为性能与体验留出调节参数。参数可以灰度,身份、权限和终态规则不能在运行时随意漂移。

  • 服务端或对端保存已消费 challenge 到过期时间;时钟只提供额外窗口,不替代 nonce,协议域分离字符串防止签名跨功能复用。
  • 所有输入都设置大小、次数和时间预算,并在超限时返回可操作的稳定错误码。
  • 重试必须带幂等键、退避和截止时间;超过截止时间后建立新任务,而不是继续复活旧回调。

“握手防重放:Nonce、时间窗和会话绑定缺一不可”的交付标准是正常路径可用、异常路径收敛、资源有界,并且用户能理解系统为何采用当前状态。 这样得到的不是演示代码,而是能解释、能降级、能回滚的生产能力。

最容易漏掉的失败路径

生产问题往往发生在两个正确动作同时到达时。需要逐条检查迟到消息、重复执行、资源耗尽和版本交叉,而不是只补当前堆栈显示的那一行。

  • 只校验五分钟时间戳允许窗口内无限重放;同一签名同时能表示“连接”和“接受文件”会造成跨协议攻击。
  • 失败被压成一个布尔值,调用方无法区分可重试、需用户介入与永久拒绝,最终形成无限循环。
  • 没有背压或配额时,慢消费者会把内存、队列长度与尾延迟一起推高,最后拖累无关用户。

上线前怎样验证

验证时同时观察两端状态、持久化记录和可观测指标。单看某个按钮或一次接口响应,无法证明整个闭环成立。

  1. 捕获合法握手后在同会话、另一会话、另一对端和窗口内外重放,所有非原始上下文都必须稳定拒绝。
  2. 让刷新、取消、超时和远端完成在同一调度窗口发生,断言系统只产生一个终态和一次副作用。
  3. 对日志和埋点做字段白名单检查,证明内容载荷、密钥、完整 IP 与用户可识别信息不会离开设备。

完成并不等于主路径跑通,而是每个终态都能对账、每个自动动作都受用户意图约束、每个成本都有明确上限。

把方法变成一次真实连接

打开 uCopy,让两台设备在浏览器里安全连接并开始传输。

开始免费使用