Case Study · 跨領域作品 · 桌面應用
Kaizei
Personal Finance OS — 台美股投資 / 智能記帳 / 雙式帳本
痛點
個人理財軟體的兩個結構性問題:(1) 多裝置同步必然牽涉雲端,但把 API key 跟交易紀錄交給第三方 server形同把鑰匙交出去; (2) 主流 Electron 應用安全做得草率,CSP 缺失、Node.js 整合一打開、API key 平文存 config 檔。
Kaizei 的設計目標:所有功能(台 / 美股自動更新、雙式記帳、報表、Gemini 分析)都做齊,但server 物理上無法讀取使用者資料, 而且把桌面端的 OS 級 / sandbox 級防護都做到位。
系統架構
桌面 + 邊緣 + 物件儲存的三層分離。Server 只看密文,認證與解密在使用者裝置完成。
- 1 · 使用者主密碼
本機輸入主密碼,永不離開使用者裝置。透過 Web Crypto 衍生兩把獨立金鑰。
- 2 · 雙金鑰衍生(PBKDF2 310,000 iterations)
authKey(送 server 做身份驗證)與 encKey(留在裝置、加 / 解密 vault 用)。兩者由同一密碼但不同 salt 衍生,互不可推導。
- 3 · 本機 AES-256-GCM 加密
vault 資料(API keys、設定、敏感欄位)以
encKey加密成 ciphertext 後才送雲端。Server 收到的是已加密的 binary blob。 - 4 · Cloudflare Worker(Hono + 自寫 JWT)
Worker 用 SHA-256(authKey + server pepper) 比對使用者身份、發 30 天 HS256 JWT。即使 JWT 被竊,攻擊者拿到的仍是 server 也讀不懂的密文。
- 5 · Supabase(PostgreSQL + RLS)
RLS 設成無 public policy ── 只有 Worker 用 service_role 可寫。GitHub Actions 每日 02:00 UTC ping 一次防止免費 tier 暫停。
設計亮點 1 ── 零知識加密 vault
最關鍵的設計:server 物理上無法解密使用者資料。即使 server 完全被入侵、DB 被脫庫、攻擊者拿到管理員權限, 撈出來的仍是 AES-GCM ciphertext,沒有使用者主密碼就無法還原成明文。
具體實作細節:
- PBKDF2 310,000 iterations(OWASP 2023 建議下限)由主密碼 + 兩組獨立 salt 衍生 authKey 與 encKey
- Server pepper 額外加在 authKey hash,即使 DB salt 外洩也無法離線爆破
- JWT 30 天到期,洩漏的 JWT 仍只能看到密文
- Web Crypto API 全程用瀏覽器 / Electron 原生 crypto,無第三方加密庫信任問題
Trade-off
- 主密碼遺失 = 資料無法救回。沒有後門 = 沒有「忘記密碼」選項。對使用者教育要做足
- 每次解鎖延遲 ~ 200-400ms(PBKDF2 設計如此)。為了安全的可接受成本
- 同步衝突解決受限:server 看不懂內容,無法做欄位級 merge,只能整包覆蓋(last-write-wins)
設計亮點 2 ── 桌面端深層防護
零知識保護「server 看不到」這條線。Electron 桌面端則需要另一套縱深防護避免本機被攻:
- OS 金鑰庫整合
Windows DPAPI / macOS Keychain 對本機儲存的 API key(即便已是 vault 的一部分)做第二層OS-level 加密,與使用者帳號 / 硬體綁定。
- Electron sandbox 全開
sandbox: true+nodeIntegration: false+contextIsolation: true。Renderer 無 Node.js 直接存取,main process 透過 IPC 嚴格白名單。 - CSP 強制 + DOMPurify
Production build 自動移除
'unsafe-inline'。所有可能含 HTML 的內容(從 GitHub Releases 抓的 changelog、使用者輸入備註)強制走 DOMPurify。
設計亮點 3 ── 資料管道與供應鏈防護
- Excel 匯入 ReDoS 防護
檔案大小硬限制 20 MB(阻擋 ReDoS attack vector)+ 匯入前自動快照(最多 5 份本地備份)+ 一鍵還原無需密碼。
- TypeScript strict mode 零容忍
v2.4.17 全面啟用
strict: true,修正 32 個既存型別錯誤達 0 errors 基線。型別安全 = 編譯期消除整類 bug。 - Dependabot 每週掃描
npm 套件漏洞每週自動掃描 + 自動 PR。Secret Scanning + Push Protection 防 secret 誤推送。
- 公開 release mirror(auditable binaries)
App 主 repo 私有,但 release 同步至公開 yu8812/kaizei-releases,使用者可以驗證二進位檔的 hash 與 release notes。
技術棧
反思 / 未來方向
- 無後門設計與「忘記密碼」之間的張力 ── 主密碼遺失 = 資料無法救回是零知識架構的必然代價。可選的中間方案(Shamir Secret Sharing 三選二恢復、社交回復)會增加實作複雜度與信任假設。值得探討的設計命題。
- Electron 桌面應用的真實攻擊面評估 ── 多層防護(sandbox + CSP + OS keychain + AES)做了,但對應的 threat model 是否過 / 不足,需要對應實證攻擊測試(如 sandbox escape 漏洞研究)。
- 跨機器 vault 同步的衝突解決 ── 目前 last-write-wins。能否在不破壞零知識的前提下做欄位級 CRDT merge?這是密碼學 + 分散式系統的有趣交叉問題。
延伸閱讀
- Kaizei 官方網站 ── 含完整安全架構深度說明(PBKDF2 → AES-256-GCM 流程圖)
- ExClinCalc Case Study(醫療端的多角色安全設計:RLS + TOTP + 稽核)
- ClinCalc Case Study(民眾端的本地優先 + 結構化注入)