功能说明
示例实现 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 两条错误。可以修改摘要中的一个字符,确认长度与十六进制校验。