代表性面试主题

后端面试:如何在不中断服务的情况下轮换 Webhook 密钥?

后端困难
Offer.cc 编辑团队发布 更新

题干

供应方必须在持续投递期间轮换 Webhook 签名密钥。你如何避免拒绝合法事件或继续接受过期签名?

题目与场景

接收方正在验证签名请求,供应方准备更换密钥。轮换必须容纳在途重试和多个发送副本,不能出现验签空窗,也不能暴露密钥。

面试官在考察什么

  • 保留原始请求体验签并使用恒定时间比较。
  • 设计有界的当前密钥与退役密钥重叠期。
  • 分离轮换状态、重放防护、可观测性和回滚。

作答前的澄清问题

  • 谁控制轮换,发送方能否提供密钥标识或版本?
  • 投递重试最长持续多久,允许多少时钟偏差?
  • 发送方能否双签名,还是接收方必须暂时接受两把密钥?
  • 事件 ID、时间戳和原始负载是否可用于重放检查?

30 秒回答框架

我会先生成新密钥并分发到所有接收方,然后进入短暂重叠期。重叠期间优先依据密钥 ID 验证;没有 ID 时只在有界窗口内尝试当前与退役密钥,同时校验时间戳并去重事件 ID。监控按版本统计验签结果,等旧版本流量在重试窗口结束后归零再退役。窗口关闭前保留回滚能力。

分步深挖

1. 保留签名字节

先把请求体作为原始字节读取,再解析 JSON。严格按供应方规则拼接时间戳、分隔符和负载,使用恒定时间比较 MAC,并尽早拒绝格式错误或超大负载。

2. 建模密钥版本

保存当前与退役版本、创建时间、过期时间、供应方范围和状态,例如 PENDINGOVERLAPRETIRED。密钥 ID 可以避免试验验签;没有 ID 时限制双密钥回退,并记录成功版本。

3. 安全发布

通过密钥管理器分发新密钥,原子重载接收方并执行签名金丝雀请求。观察到准备完成后再让发送方切换。旧密钥至少保留最长重试时长加时钟偏差裕量。

4. 阻断重放

要求签名时间戳处于有界容差内,并保存事件 ID 或摘要,保留期覆盖重试。验签必须先于入队;重复的合法投递可以确认成功,但不能重复业务副作用。

5. 观测与退役

按密钥版本统计成功验签、过期时间戳、重复 ID、格式错误和队列结果,不记录密钥或完整敏感负载。重叠期与重试窗口结束后再退役旧版本;新版本失败时恢复旧版本并告警。

高质量示范回答

“我会把新版本写入密钥管理器,重载所有接收方并用金丝雀请求验证,再切换发送方。重叠期内接受当前和退役版本,优先用密钥 ID 选择,同时校验签名时间戳并去重事件 ID。我会按版本观察验签情况,等待发送方重试窗口加时钟偏差结束后再退役旧密钥。新版本失败时保留旧密钥回滚;日志只记录计数和安全 ID,不记录密钥或原始负载。”

常见失误

  • 同时替换所有密钥 → 旧签名重试会失败 → 设置重叠期。
  • 先解析 JSON 再验签 → 规范化可能改变原始字节 → 先验签原始请求体。
  • 永久接受两把密钥 → 过期凭证长期有效 → 按重试和时钟偏差设过期时间。
  • 记录签名或密钥 → 观测系统变成泄露源 → 只记录版本计数和安全标识。

追问与回答

发送方不能双签怎么办?

接收方预加载新密钥,并在有界窗口内同时接受两个版本。协调发送方切换,监控版本验签结果,旧版本至少保留到最长重试期结束。

如何确定重叠时长?

依据发送方重试上限、队列延迟、时钟偏差容忍和事故裕量。明确截止时间,并在临近退役时对旧版本流量告警,不能只依据平均延迟猜测。

攻击者重放旧的合法事件怎么办?

拒绝超出时间容差的时间戳,并去重事件 ID 或签名负载摘要。重放记录至少保留到接受时间窗口和业务重试窗口结束。

公开来源

同类题目