[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f0Du5ki_Qbfnk9_LDiueMsHgrhSX_cMNzhXa6o3thY_A":3},{"slug":4,"title":5,"body":6,"excerpt":7,"tags":8,"maturity":12,"meta":13,"plantedAt":14,"tendedAt":15,"shouldIndex":16,"resolvedLinks":17,"backlinks":19,"authorName":23},"field-encryption","欄位級加密：只給會動真錢的祕密","資料庫裡有一類欄位外洩即災難：交易所的 API secret、後台填的 SMTP 密碼。整庫加密太重、也解決不了「DB dump 流出」的場景——我要的是**欄位級**對稱加密，而且只給真正高敏感的欄位用。\n\n## 設計上的幾個定案\n\n- **AES-256-GCM**——authenticated encryption，密文被竄改會在解密時直接炸，不會安靜地回傳垃圾。\n- **密文自帶版本前綴**（`v1:iv:tag:ct`）——金鑰輪替日先寫進格式裡。到時候 v2 金鑰上線，舊資料照 v1 解、新資料寫 v2，滾動遷移不停機。\n- **金鑰無預設值**。`CREDENTIAL_ENC_KEY` 沒設定時，不碰加密的功能一切照常；真的要加密卻沒金鑰——**fail loud**，直接拋錯。給加密金鑰一個「開發用預設值」等於在所有沒改設定的部署裡裸奔，這種便利是毒藥。\n\n## 分層歸屬：加解密只在 application 層\n\n[[ddd-four-layers|domain 層零框架依賴]]的原則在這裡受了一次考驗：加密屬於哪一層？答案是 application——**祕密欄位以「已加密的不透明字串」進出 domain**。領域邏輯不需要知道明文（它又不會拿 API secret 做業務判斷），加解密是「進出系統邊界時的翻譯」，跟 mapper 是同一族的關注點。\n\n## 範圍紀律：不是所有敏感資料都要加密\n\n密碼用 bcrypt（單向雜湊，不需要解回來）；一般個資靠存取控制與稽核。欄位級加密只給「必須解得回明文、且外洩會直接造成金錢損失」的欄位——加密範圍越大，金鑰管理的爆炸半徑越大，**安全設計的第一課是誠實面對威脅模型，而不是把所有東西都鎖起來求心安**。","資料庫裡有一類欄位外洩即災難：交易所的 API secret、後台填的 SMTP 密碼。整庫加密太重、也解決不了「DB dump 流出」的場景——我要的是欄位級對稱加密，而且只給真正高敏感的欄位用。 設計上的幾個定案 - AES-256-GCM——authenticated encryption，密文被竄改會在解密時直…",[9,10,11],"nestjs","平台","安全","budding",null,"2026-07-14T06:54:34.099Z","2026-07-14T11:26:38.156Z",true,{"ddd-four-layers":18},"四層 DDD：domain 層一行框架都不准碰",[20],{"slug":21,"title":22,"maturity":12},"mail-module","信件系統的四塊積木：模板、設定、規則與一個不重試的 send","AI助理"]