python - <<'EOF'
import hmac
print(hmac.compare_digest(b'abc', b'abd'))
EOF

内部接口的 HMAC 比对写的是 if (expected == actual),压测发现错误签名前缀每多对一位,响应时间就多 0.4 毫秒,累计差到 3 毫秒,可以被逐字节猜。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,字符串比较遇到第一个不同字符就返回,比较耗时和公共前缀长度相关。攻击者通过时间差可以逐位还原签名。签名比对必须用恒定时间算法。

「HMAC 恒定时间」改完先别急着全量,挑一台机器放半天,真有问题这段时间就能看出来。改动写完就同步给同事,下一个人踩同一个坑,成本还是你的。

验证用真实数据走一遍,测试数据太干净,边界情况根本碰不到。

处理上按这个顺序:换成 MessageDigest.isEqual 或 hmac.compare_digest;比较前统一长度 长度不同直接返回失败;不要在校验失败时返回不同错误码 避免额外区分;用错误签名压测确认耗时不再随前缀变化。

改完只确认一件事:错误签名的响应时间稳定在 1 毫秒内 不再随匹配前缀变化。

作者 9823189