題干與適用場景
請實作一個 ML-DSA 簽章驗證封裝:呼叫方提供演算法、公開金鑰、訊息、簽章和上下文。你會如何校驗輸入、避免跨協定重放,並設計錯誤處理與測試?
面試官考察點
- 是否複用經過驗證的 FIPS 204 實作,而不是自行重寫格密碼原語。
- 是否把演算法識別、公開金鑰、訊息、簽章和 context 作為不可混淆的輸入。
- 是否區分簽章無效、輸入格式錯誤、演算法不支援和內部故障,避免洩露敏感細節。
- 是否透過上下文綁定、固定介面和向量測試防止跨協定重放與實作漂移。
回答前需要釐清的問題
- 使用 ML-DSA 的哪種參數集,函式庫是否經過 FIPS 204 向量驗證?
- context 由哪個協定定義,是否允許空值,編碼和長度限制是什麼?
- 驗證失敗是普通業務結果,還是需要觸發告警與稽核?
- 訊息是否串流、是否需要預雜湊介面,以及金鑰輪換如何處理?
30 秒回答框架
我會把封裝限制在已驗證的 ML-DSA 函式庫 API。先根據明確演算法識別選擇參數集,嚴格校驗位元組輸入和 context,再把 protocol context 與訊息一起交給函式庫驗證。回傳值只區分 valid、invalid、unsupported 和 malformed,不把例外堆疊回傳給呼叫方。測試涵蓋官方向量、竄改、錯誤參數集、跨 context 重放、邊界長度、並行和金鑰輪換;私鑰和完整訊息不進日誌。
分步驟深入解答
1. 設定封裝邊界
FIPS 204 規定 ML-DSA 的簽章生成和驗證演算法;RFC 9882 說明 CMS 使用時,hedged 與 deterministic 簽章使用相同驗證演算法。業務程式不應實作 NTT、取樣或拒絕取樣,而應固定依賴版本、參數集和經測試的函式庫介面。
2. 做輸入與上下文校驗
介面先檢查演算法識別是否允許、公開金鑰和簽章位元組是否符合所選參數集、訊息是否處於允許大小,並按協定規範編碼 context。context 不是日誌標籤,它參與簽章域分離;驗證時必須使用簽章生成方約定的同一值。缺失或錯誤 context 直接回傳 malformed/invalid,不能自動嘗試空 context。
3. 設計安全錯誤語意
對外回傳結構化結果,例如 valid、invalid、unsupported、malformed,避免把函式庫例外、金鑰內容或解析細節回顯。統計和稽核只記錄演算法、版本、結果類別與 request id。內部例外要進入受控錯誤通道並觸發告警,不能把「函式庫崩潰」偽裝成簽章無效。
4. 用向量和協定測試鎖定行為
先跑 NIST ACVP 或 FIPS 204 相容向量,再測試一位竄改、截斷、拼接不同 context、錯誤演算法識別和舊金鑰。驗證跨協定場景時,確保同一訊息在不同 context 下不會被接受。並行呼叫使用不可變輸入,金鑰輪換同時接受明確的舊版本視窗,過期後拒絕。
高品質示範回答
我會把實作限制為已驗證函式庫的薄封裝,不重寫 ML-DSA 原語。呼叫方必須明確提供演算法識別、參數集、公開金鑰、訊息、簽章和協定 context;封裝先校驗格式與大小,再把同一個 context 傳給驗證 API,絕不在失敗時自動嘗試其他參數集或空 context。對外只回傳 valid、invalid、unsupported、malformed 四類結果,內部例外單獨告警,日誌不含私鑰和訊息。用 FIPS/ACVP 向量、竄改、截斷、跨 context 重放、金鑰輪換和並行測試鎖定行為,並固定函式庫版本與參數配置。
常見錯誤
- 自己實作 ML-DSA 的 NTT、取樣或拒絕取樣。
- 忽略演算法識別,讓同一公鑰在不同參數集間嘗試驗證。
- 驗證失敗時自動重試空 context 或其他 context。
- 把函式庫例外、簽章無效和輸入格式錯誤混成一個無依據的成功/失敗。
- 將完整訊息、金鑰或例外堆疊寫入日誌。
- 只寫 happy path,沒有官方向量、竄改、重放和輪換測試。
追問及應對
hedged 和 deterministic 簽章需要不同驗證程式嗎?
不需要。RFC 9882 明確指出兩種簽章使用相同的驗證演算法;封裝不應根據簽章模式選擇兩套驗證路徑。
為什麼 context 能防跨協定重放?
它把簽章綁定到協定域。相同訊息和金鑰在不同 context 下應產生不同的驗證語意;驗證器不能在 context 缺失時猜測或回退。
如何處理函式庫升級?
鎖定參數集和函式庫版本,先用官方向量與歷史相容樣本做回歸,再小比例切換。記錄版本和結果類別,發現差異時保留舊驗證路徑直到完成遷移。