客戶端加密的安全邊界
一句話:framework 的客戶端加密只是 obfuscation,防止 cookie / localStorage 內容被旁人偶然看到。不構成真正的安全屏障。 真正的安全依賴 HTTPS + 後端鑑權。
加密在哪裡被使用
framework 在 4 個地方做客戶端加密(全部 AES-CBC + 隨機 IV):
| 位置 | 入口 | 加密內容 |
|---|---|---|
| Cookie | useCookie('xxx')(utils/cookie.ts) | tokenInfo / deviceId / channel_code / share_code 等 |
| localStorage | useLocal('xxx', init) | AccountInfo(帳號 / 密碼 / 「記住我」勾選)等業務自定義 |
| sessionStorage | useSession('xxx', init) | 業務自定義 |
| API 請求 | request 插件自動加密 POST body | 透過 aes-dynamic(HmacSHA256 按 requestId 派生每請求金鑰) |
為什麼「不是真正的安全」
加密金鑰來自 runtimeConfig.public.cacheAesKey / runtimeConfig.public.apiKey:
// nuxt.config.ts —— 專案常數直接寫實值(隨程式碼走,執行期同名 NUXT_PUBLIC_* env 仍可覆蓋)
runtimeConfig: {
public: {
cacheAesKey: 'your-16-byte-key', // 16 / 24 / 32 位元組
apiKey: 'your-backend-key', // 與後端約定的請求加密金鑰
}
}
任何在 runtimeConfig.public.* 下的欄位都會被 Nuxt 序列化進 __NUXT__.config.public 注入到客戶端 HTML,任何使用者打開 DevTools 一行 JS 就能讀到:
// 瀏覽器主控台
window.__NUXT__.config.public.cacheAesKey // 直接拿到金鑰
window.__NUXT__.config.public.apiKey
拿到金鑰就能解 cookie / localStorage / 請求體 — 加密形同虛設。這是所有純前端加密的固有局限,不是 framework 的設計失誤:客戶端要解密就必須能拿到金鑰,金鑰要發給客戶端就必然能被反編譯看見。
真正的安全靠什麼
| 想防什麼 | 真正的防禦 |
|---|---|
| 中間人竊聽傳輸內容 | HTTPS / TLS(不是 framework 加密) |
| 後端識別非法請求 | 後端鑑權:token 校驗 / 請求簽名校驗 |
| 資料庫洩露後明文可讀 | 欄位級加密(金鑰在 HSM/KMS,不在前端 bundle) |
| 防止使用者篡改本地資料 | 後端再驗證一遍(前端加密擋不住,只能拖延幾秒) |
那 framework 的客戶端加密還有什麼用
仍然有意義但價值有限的幾個場景:
- 防止 DevTools Cookies / Local Storage 面板一眼看到敏感欄位 勾選「記住我」後,密碼在 localStorage 裡是密文而非明文 JSON。
- 防止 cookie 內容隨每個請求飛出去時被中間鏈路(log / proxy)順手記錄明文 token / userInfo 是密文,HTTPS 之外的鏈路抓到的也是密文。
- 擋住自動化爬蟲的「low-effort」攻擊 爬蟲不解 AES,原文搜不到關鍵字。
設計建議
把 framework 加密當成 obfuscation,不要當作安全屏障。
- ✅ 用
useCookie/useLocal/useSession存登入態、使用者偏好、UI 快取 — obfuscation 帶來的邊際收益就夠了。 - ✅ 用 framework 請求加密 — 防 log 明文 + 防 low-effort 爬蟲。
- ❌ 不要把「加密了」當成可以放敏感欄位的理由。 密碼必須靠 HTTPS + 後端校驗 + 使用者主動選擇(「記住我」)的多重防禦組合。
- ❌ 不要在前端做「業務敏感資料加密後存資料庫」的設計 — 那是後端欄位級加密的活,金鑰不該出現在前端。
已規劃的演進
- AES-CBC → AES-GCM(已擱置,詳見 framework#2 關閉評論):後端框架需相容老專案、ECB 加密不能換,而 Web Crypto API 原生不支援 ECB,遷移整體擱置;待後端框架升級大版本時重新評估。
- 客戶端金鑰協商(不在規劃):技術上可以用 ECDH 在登入時協商一份 session 金鑰,但工程成本遠大於收益(HTTPS 已經解決 99% 的傳輸安全)。