标准答案

  1. 服务端和调用方先约定规范化字符串,通常包含 HTTP 方法、路径、查询参数、时间戳、随机数和请求体摘要,再使用共享密钥计算 HMAC。
  2. 时间戳让服务端拒绝过旧或未来过远的请求,缩短攻击者截获请求后重放的有效窗口。
  3. 随机数或 nonce 需要在有效窗口内去重,防止攻击者在时间窗口内重复发送完全相同的已签名请求。
  4. 请求体摘要保证签名与实际 body 一致,避免攻击者替换金额、收款方或其他内容后仍复用原签名。
  5. 实现还应使用恒定时间比较、密钥轮换、算法版本和安全的密钥存储;签名不能替代 TLS。

题目解析

签名协议最常见问题是规范化不一致:参数排序、空值、编码、换行和 JSON 字段顺序若未约定,双方会产生不同签名。

nonce 去重存储要按调用方和有效窗口设计。无限保存会浪费资源,不保存则无法阻止窗口内重放。

代码示例

双方必须对待签名字符串的字段顺序和编码采用完全一致的规则。

Text
POST
/v1/payments
timestamp=1720000000
nonce=8d7d...
sha256(body)=4f9b...

signature = HMAC-SHA256(secret, canonicalRequest)

常见误区

  • 只签名 URL,不签名请求方法、时间戳或请求体。
  • 校验时间戳却没有 nonce 去重,窗口内仍可被重放。
  • 使用普通字符串比较签名,或把签名密钥写进客户端。

作者信息