具代表性的面試主題

前端面試:如何儲存不可匯出的 Web Crypto 密鑰?

前端困難
Offer.cc 編輯團隊發佈 更新

題幹

Web 應用要加密本地草稿,避免 XSS 直接從儲存讀取明文密鑰。你如何設計,還有哪些限制?

題目與情境

應用在瀏覽器中加密本地資料,並希望跨工作階段使用密鑰。設計應降低密鑰暴露,但必須說明限制:同源腳本仍可能呼叫允許的操作,使用者也可能失去恢復能力。

面試官在考察什麼

  • 理解安全上下文、CryptoKey 可匯出性和密鑰用途。
  • 分離加密資料儲存、密鑰恢復與威脅建模。
  • 解釋瀏覽器密碼學不能讓 XSS 無害。

作答前的釐清問題

  • 威脅是被盜儲存記錄、被動攻擊者,還是主動同源腳本?
  • 登出、裝置遺失、密碼重設和瀏覽器設定刪除後資料是否必須保留?
  • 能否用使用者口令或 WebAuthn 憑證解鎖包裹密鑰?
  • 需要哪些演算法、用途、瀏覽器支援和遷移路徑?

30 秒回答框架

我會要求 HTTPS,產生或匯入 CryptoKey,把 extractable 設為 false,只授予必要用途,並把瀏覽器管理的密鑰句柄存入 IndexedDB,而不是匯出原始位元組。密文、隨機數、演算法參數和版本與密鑰分開保存。同時設定 CSP、依賴審查和恢復方案,並說明應用開啟時同源腳本仍可能呼叫解密 API 或讀取記憶體中的明文。

分步深挖

1. 定義威脅模型

不可匯出性限制意外匯出和部分儲存盜竊路徑,但不能阻止在同源執行的腳本要求應用解密或讀取記憶體明文。承諾安全性前先聲明邊界。

2. 建立或匯入密鑰

使用受支援演算法和專用用途,例如加密與解密。在安全上下文產生密鑰,或匯入包裹材料並設定目標可匯出性。拒絕異常演算法參數,不把原始密鑰材料放入 localStorage。

3. 安全持久化密文

保存密文、每次加密的新隨機數、認證元資料、密鑰版本和資料模式版本。使用 AES-GCM 等認證加密,並保證同一密鑰下每條記錄的隨機數唯一。把租戶或使用者範圍放進關聯資料,而不是隱含信任決策。

4. 規劃恢復與輪換

瀏覽器設定刪除或裝置遺失可能讓不可匯出密鑰無法使用。上線前提供明確恢復路徑,例如口令派生的包裹密鑰或伺服器重新加密流程,不能靜默降級為明文。密鑰版本化並事務性遷移記錄。

5. 測試與運營

測試不支援演算法、不安全上下文、配額錯誤、中斷寫入、隨機數重用、版本遷移、登出和恢復失敗。設定 CSP、審查依賴、不記錄敏感日誌,只統計解密失敗而不記錄明文。

高品質示範回答

「我會要求 HTTPS,產生用途受限且 extractable 為 false 的 CryptoKey,只把瀏覽器管理的句柄放進 IndexedDB。每條記錄保存密文、唯一隨機數、認證元資料和密鑰版本。由於設定遺失可能導致不可匯出密鑰無法恢復,我會在上線前定義恢復流程。CSP 與依賴控制能降低主動腳本風險,但同源 XSS 仍可能呼叫允許的解密操作或讀取應用開啟時的明文。」

常見失誤

  • 把原始密鑰放入 localStorage → 儲存被盜就能解密 → 持久化不可匯出密鑰句柄。
  • AES-GCM 重用隨機數 → 機密性與完整性可能失效 → 每個密鑰和記錄使用唯一隨機數。
  • 聲稱解決了 XSS → 同源程式碼仍能使用應用權限 → 說明主動腳本限制。
  • 跳過恢復設計 → 設定遺失會摧毀資料存取 → 定義包裹、重設和遷移流程。

追問與回答

IndexedDB 能讓密鑰免受 XSS 嗎?

不能。它避免把原始位元組放進簡單儲存 API,但同源腳本仍可能存取資料庫或呼叫應用程式碼。應設定 CSP、審查依賴並採用現實威脅模型。

使用者遺失裝置後如何恢復?

用使用者持有的秘密或恢復憑證派生密鑰包裹資料密鑰,或透過認證伺服器流程重新加密。解釋離線與重設取捨,不能靜默產生無法解密舊資料的新密鑰。

輪換時可以匯出密鑰嗎?

只有策略允許才可以。更推薦產生新密鑰,在兩個版本都可用時遷移記錄;需要包裹時保護包裹密鑰並稽核轉換。

公開來源

同類題目