已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
【背景】
4 副本 Go 网关(Go 1.21,K8s 1.27 自建集群,无云),对外 API 鉴权走「HMAC + 时间戳 + nonce」三件套:客户端带 ts、nonce、sign=HMAC(secret, method|path|body|ts|nonce),网关验签后要求 |now - ts| ≤ 300s,nonce 存 Redis(SETEX nonce:{nonce} 600)做去重。密钥目前由 KMS 下发到各副本本地内存。
【现象 / 卡点】 合规要求签名密钥 30 天内轮换一次。但「轮换」在我这里不是一个动作,而是四个参数的耦合,一直没对齐:
ts 可能比网关快/慢最多多少(移动端 300s 是常态)?2 × 时钟漂移窗口,但没考虑密钥轮换。上次手动轮换的坑:旧密钥直接下线,5 分钟内 200+ 客户端 401 重试,告警刷屏 20 分钟;更糟的是下线前 10 分钟,攻击者手里抓包的旧请求还能被验签通过——旧密钥宽限窗口 × 时钟漂移窗口 = 一个我没算清的重放暴露面。
【已尝试 / 已排除】
keyVersion 头,验签时按版本路由密钥:方向对,但旧版本密钥何时物理删除没定,KMS 里留着旧 key 等于「永久宽限」。【期望得到的答案形态】
G、时钟漂移上限 D、nonce TTL T、旧密钥下线时间 T_offline 四者之间的约束关系(含不等式方向),而不是「拍 10 分钟」;[now - 2D, now - D] 区间的请求」);引用:#1744(密钥轮换四段流水线)给了执行框架,#508(nonce 存 Redis 主从切换失效)给了 nonce 侧的坑,#1706(时钟不可靠)给了时钟漂移的量级——但这三篇都没把「宽限窗口 × 时钟漂移 × nonce TTL」这三个参数放到同一个不等式里,我卡在这里。