題目與情境
接收方正在驗證簽名請求,供應方準備更換密鑰。輪換必須容納在途重試和多個發送副本,不能出現驗簽空窗,也不能暴露密鑰。
面試官在考察什麼
- 保留原始請求本文驗簽並使用恆定時間比較。
- 設計有界的目前密鑰與退役密鑰重疊期。
- 分離輪換狀態、重放防護、可觀測性和回滾。
作答前的釐清問題
- 誰控制輪換,發送方能否提供密鑰識別碼或版本?
- 投遞重試最長持續多久,允許多少時鐘偏差?
- 發送方能否雙簽名,還是接收方必須暫時接受兩把密鑰?
- 事件 ID、時間戳和原始負載是否可用於重放檢查?
30 秒回答框架
我會先產生新密鑰並分發到所有接收方,然後進入短暫重疊期。重疊期間優先依據密鑰 ID 驗證;沒有 ID 時只在有界窗口內嘗試目前與退役密鑰,同時校驗時間戳並去重事件 ID。監控按版本統計驗簽結果,等舊版本流量在重試窗口結束後歸零再退役。窗口關閉前保留回滾能力。
分步深挖
1. 保留簽名字節
先把請求本文作為原始位元組讀取,再解析 JSON。嚴格按供應方規則拼接時間戳、分隔符和負載,使用恆定時間比較 MAC,並盡早拒絕格式錯誤或過大負載。
2. 建模密鑰版本
保存目前與退役版本、建立時間、過期時間、供應方範圍和狀態,例如 PENDING、OVERLAP、RETIRED。密鑰 ID 可以避免試驗驗簽;沒有 ID 時限制雙密鑰回退,並記錄成功版本。
3. 安全發布
透過密鑰管理器分發新密鑰,原子重載接收方並執行簽名金絲雀請求。觀察到準備完成後再讓發送方切換。舊密鑰至少保留最長重試時長加時鐘偏差裕量。
4. 阻斷重放
要求簽名時間戳處於有界容差內,並保存事件 ID 或摘要,保留期覆蓋重試。驗簽必須先於入隊;重複的合法投遞可以確認成功,但不能重複業務副作用。
5. 觀測與退役
按密鑰版本統計成功驗簽、過期時間戳、重複 ID、格式錯誤和佇列結果,不記錄密鑰或完整敏感負載。重疊期與重試窗口結束後再退役舊版本;新版本失敗時恢復舊版本並告警。
高品質示範回答
「我會把新版本寫入密鑰管理器,重載所有接收方並用金絲雀請求驗證,再切換發送方。重疊期內接受目前和退役版本,優先用密鑰 ID 選擇,同時校驗簽名時間戳並去重事件 ID。我會按版本觀察驗簽情況,等待發送方重試窗口加時鐘偏差結束後再退役舊密鑰。新版本失敗時保留舊密鑰回滾;日誌只記錄計數和安全 ID,不記錄密鑰或原始負載。」
常見失誤
- 同時替換所有密鑰 → 舊簽名重試會失敗 → 設定重疊期。
- 先解析 JSON 再驗簽 → 正規化可能改變原始位元組 → 先驗簽原始請求本文。
- 永久接受兩把密鑰 → 過期憑證長期有效 → 按重試和時鐘偏差設定過期時間。
- 記錄簽名或密鑰 → 觀測系統變成洩露源 → 只記錄版本計數和安全識別碼。
追問與回答
發送方不能雙簽怎麼辦?
接收方預載新密鑰,並在有界窗口內同時接受兩個版本。協調發送方切換,監控版本驗簽結果,舊版本至少保留到最長重試期結束。
如何確定重疊時長?
依據發送方重試上限、佇列延遲、時鐘偏差容忍和事故裕量。明確截止時間,並在臨近退役時對舊版本流量告警,不能只依據平均延遲猜測。
攻擊者重放舊的合法事件怎麼辦?
拒絕超出時間容差的時間戳,並去重事件 ID 或簽名負載摘要。重放記錄至少保留到接受時間窗口和業務重試窗口結束。