题目与场景
接收方正在验证签名请求,供应方准备更换密钥。轮换必须容纳在途重试和多个发送副本,不能出现验签空窗,也不能暴露密钥。
面试官在考察什么
- 保留原始请求体验签并使用恒定时间比较。
- 设计有界的当前密钥与退役密钥重叠期。
- 分离轮换状态、重放防护、可观测性和回滚。
作答前的澄清问题
- 谁控制轮换,发送方能否提供密钥标识或版本?
- 投递重试最长持续多久,允许多少时钟偏差?
- 发送方能否双签名,还是接收方必须暂时接受两把密钥?
- 事件 ID、时间戳和原始负载是否可用于重放检查?
30 秒回答框架
我会先生成新密钥并分发到所有接收方,然后进入短暂重叠期。重叠期间优先依据密钥 ID 验证;没有 ID 时只在有界窗口内尝试当前与退役密钥,同时校验时间戳并去重事件 ID。监控按版本统计验签结果,等旧版本流量在重试窗口结束后归零再退役。窗口关闭前保留回滚能力。
分步深挖
1. 保留签名字节
先把请求体作为原始字节读取,再解析 JSON。严格按供应方规则拼接时间戳、分隔符和负载,使用恒定时间比较 MAC,并尽早拒绝格式错误或超大负载。
2. 建模密钥版本
保存当前与退役版本、创建时间、过期时间、供应方范围和状态,例如 PENDING、OVERLAP、RETIRED。密钥 ID 可以避免试验验签;没有 ID 时限制双密钥回退,并记录成功版本。
3. 安全发布
通过密钥管理器分发新密钥,原子重载接收方并执行签名金丝雀请求。观察到准备完成后再让发送方切换。旧密钥至少保留最长重试时长加时钟偏差裕量。
4. 阻断重放
要求签名时间戳处于有界容差内,并保存事件 ID 或摘要,保留期覆盖重试。验签必须先于入队;重复的合法投递可以确认成功,但不能重复业务副作用。
5. 观测与退役
按密钥版本统计成功验签、过期时间戳、重复 ID、格式错误和队列结果,不记录密钥或完整敏感负载。重叠期与重试窗口结束后再退役旧版本;新版本失败时恢复旧版本并告警。
高质量示范回答
“我会把新版本写入密钥管理器,重载所有接收方并用金丝雀请求验证,再切换发送方。重叠期内接受当前和退役版本,优先用密钥 ID 选择,同时校验签名时间戳并去重事件 ID。我会按版本观察验签情况,等待发送方重试窗口加时钟偏差结束后再退役旧密钥。新版本失败时保留旧密钥回滚;日志只记录计数和安全 ID,不记录密钥或原始负载。”
常见失误
- 同时替换所有密钥 → 旧签名重试会失败 → 设置重叠期。
- 先解析 JSON 再验签 → 规范化可能改变原始字节 → 先验签原始请求体。
- 永久接受两把密钥 → 过期凭证长期有效 → 按重试和时钟偏差设过期时间。
- 记录签名或密钥 → 观测系统变成泄露源 → 只记录版本计数和安全标识。
追问与回答
发送方不能双签怎么办?
接收方预加载新密钥,并在有界窗口内同时接受两个版本。协调发送方切换,监控版本验签结果,旧版本至少保留到最长重试期结束。
如何确定重叠时长?
依据发送方重试上限、队列延迟、时钟偏差容忍和事故裕量。明确截止时间,并在临近退役时对旧版本流量告警,不能只依据平均延迟猜测。
攻击者重放旧的合法事件怎么办?
拒绝超出时间容差的时间戳,并去重事件 ID 或签名负载摘要。重放记录至少保留到接受时间窗口和业务重试窗口结束。