← 中文资源

简体中文版本

用 HMAC 校验 Webhook 签名

解析 t 与 v1 签名头,用 HMAC-SHA256 重新计算摘要,通过 compare_digest 恒定时间比较,并检查时间戳是否在容忍窗口内。

阅读英文原文

功能说明

示例实现 Webhook 签名校验。发送方用 t=<时间戳>,v1=<摘要> 的格式传递签名,摘要由 HMAC-SHA256(secret, timestamp + "." + payload) 计算。接收方解析签名头,检查时间戳是否在容忍窗口内,再用 hmac.compare_digest 做恒定时间比较,避免通过响应时间推测摘要。

关键代码

message = f"{signed.timestamp}.".encode("utf-8") + payload
expected = hmac.new(secret, message, hashlib.sha256).hexdigest()
if not hmac.compare_digest(expected, signed.signature):
    raise SignatureError("signature mismatch")

时间戳参与签名,攻击者无法只替换时间戳来绕过过期检查。

使用注意

  • 容忍窗口默认 300 秒,应根据双方时钟偏差调整,不能无限放大。
  • 必须先校验时间戳再比较摘要,否则过期请求仍会消耗计算资源。
  • compare_digest 只接受同类型、同长度的字符串或字节;长度检查已在解析阶段完成。
  • 密钥应从环境变量或密钥管理服务读取,不要硬编码在仓库里。
  • 该实现只防篡改与重放,不提供加密;敏感载荷仍需 HTTPS 保护。

验证方式

示例先用固定时间戳生成签名并验证通过,再分别修改载荷和把当前时间推后 600 秒,应得到 signature mismatch 与 timestamp is outside the tolerance window 两条错误。可以修改摘要中的一个字符,确认长度与十六进制校验。