可搜尋的中繼資料,封裝後的欄位值
排程中閱讀時間 5 分鐘 作者 NT²
一座連標題都找不到的保管箱不能用。一座在伺服器上對每個密碼做全文索引的保管箱,也稱不上是保管箱。分界線在於投影過的中繼資料,與封裝後的欄位值之間。
可搜尋的中繼資料,封裝後的欄位值
主張:兩種表示形式,一條誠實的邊界
從同一套型別系統組合出各個領域說明了套件與範本如何擴展規模。這篇文章要點名這些欄位必須跨越的那條儲存邊界:清單能看見什麼,與只有解鎖之後才能看見什麼。
主張是:可搜尋的中繼資料與封裝後的欄位值,本來就該是刻意分開的兩層。 標題、類別,以及經過謹慎投影的搜尋文字,讓一座大型保管箱維持可導覽。敏感值則以可攜密文的形式離開記憶體——由穩定欄位索引定址的 CBF 內容資料塊——而不是等著下一個索引器來讀取的 JSON 鍵。
零知識不是「我們把資料庫檔案加密了」這麼一句行銷詞。它是一條規則,規定哪些位元組會為了本機使用者體驗以明文存在,哪些位元組只會以封裝盒的形式存在於磁碟、備份與選用同步之中。
限制:全部索引就無隱私,全部封裝就找不到東西
結構化保管箱有兩種主要的失敗模式。
全部索引。 把欄位對照表存成明文 JSON(或伺服器端可解密的索引),讓搜尋感覺很神奇。你換來便利,卻失去了整個產品。任何拿到資料庫檔案、備份壓縮檔,或同步服務端席位的人,都能讀到你的人生資料。「靜態加密」就變成了包在一座可搜尋蜜罐外面的一個核取方塊。
全部封裝,連標題也不例外。 只存不透明的區塊。搜尋直接死掉。使用者只能一個一個項目重新打開。結構化模型的清單體驗——也就是插槽勝過空白頁的原因——就此塌陷成一座神秘檔案庫。
還有第三種比較隱晦的失敗:加密仍然含有自由格式字串鍵的 JSON。 你得到的是密文,但沒有可演化的版面。改個名字就會弄壞讀取端。同義詞不斷增生。盲目的同步的確不該解析欄位——但你未來自己的用戶端終究得解析。
NT² 需要的是一套在數千筆項目規模下仍然好用的本機搜尋,以及一種永遠不要求邊緣理解密碼欄位的傳輸格式。
設計:儲存時投影,依索引封裝
刻意設計的明文中繼資料
清單列需要一小片明文範圍:標題、類別、生命週期旗標、清單預覽文字,以及其他篩選用欄位。標題(以及其他允許投影的文字)的全文搜尋,位於本機的 SQLite 引擎中——可參考FTS5 用於標題;篩選勝出時改用全表掃描與永遠不要把整座保管箱載入 Svelte 狀態。這份中繼資料是刻意挑選的,不是「表單裡剛好有什麼就存什麼」。
依能力旗標決定的投影
儲存時,寫入分頁只會把語意型別允許索引搜尋的欄位,投影進一份本機搜尋區塊。機密會被排除在外。清單副標題可以依照非機密欄位的優先順序來決定,讓一筆銀行項目能顯示機構名稱形狀的提示,而不必把帳號整個丟進 FTS。
投影是解鎖後的客戶端工作。它不是伺服器端對密文的解析。
領域 id 對應到傳輸欄位索引
在記憶體中,值是以語意欄位 id 鍵值化的。在加密之前,酬載編碼器會把這些 id 對應到登錄表清單中穩定的數字欄位索引,把它們打包進一個內容資料塊,再以該物件的內容金鑰把資料塊封裝成 CBF——詳情見CBF:結構化欄位離開記憶體的方式與信封文章每個物件一把金鑰:NT² Vault 內的信封加密。
flowchart LR
Edit[記憶體中的欄位對照表] --> Proj[投影安全中繼資料]
Edit --> Blob[依 fieldIndex 組成的內容資料塊]
Proj --> List[清單/FTS 欄位]
Blob --> Box[CBF 密文]
Box --> Disk[SQLite/備份/同步]
密文不會帶著一堆 password 之類的字串鍵到處流傳。它帶的是登錄表看得懂的索引。範本脈絡會隨著資料塊一起傳遞,讓讀取端知道該套用哪一套類別結構描述——而不需要邀請邊緣去解讀值本身。
邊緣始終一無所知
選用的 Premium 同步,只轉送不透明的封包與帳號中繼資料。Workers 從來拿不到你保管箱的欄位字典。如果有一個操作端工具必須解析備註內容才能「幫上忙」,那條邊界就已經失守了。姊妹邊界文章——邊緣上的盲目複本同步與Workers 允許看見什麼——與這篇文章互為表裡。
取捨:機密不是一個全域全文語料庫
你不能貼半個密碼就期待雲端搜尋幫你找到它。你也不能要求伺服器替你的醫療欄位做分類。本機投影只涵蓋型別允許的部分。附件位元組同樣不是免費的全文語料庫;除非未來某個產品介面明確表態,否則中繼資料與標題才是承擔可搜尋性的部分。
換來的是更強的保障:在只需要鎖定狀態中繼資料就夠用時,保管箱依然可以導覽;而封裝後的值,不會變成別人拿去做離線密碼字典攻擊的來源。
| 層級 | 明文角色 | 封裝角色 |
|---|---|---|
| 標題/類別 | 清單+FTS | — |
| 搜尋投影 | 允許的非機密欄位文字 | — |
| 密碼、種子、帳號數字 | — | CBF 欄位索引 |
| 邊緣同步 | 身分/帳務/不透明位元組 | 轉送封包,不解析欄位 |
我們拒絕什麼
我們拒絕伺服器端對保管箱內容做明文搜尋。 若便利性得靠操作端讀取欄位才能實現,那就不是一項功能。
我們拒絕在持久密文中散落自由格式的字串鍵。 登錄表索引的存在,就是為了讓酬載得以演化,而不必陷入同義詞的泥沼。
我們拒絕把壓縮或「磁碟加密」當成封裝內容的替代品。 CBF 與逐物件金鑰,才是項目的邊界;檔案系統層級的加密屬於別人的責任範圍。
我們拒絕「以防萬一」就把每個機密都塞進 FTS。 可搜尋性是一種能力,不是每一欄的預設值。
找得到列,也解得開封裝
有結構卻找不到,就像一個標籤被塗掉的檔案櫃。找得到卻沒有封裝,就像一份貼了掛鎖貼紙的試算表。NT² 同時保留這兩層——而且刻意讓它們保持分離。
本系列的第一條主線,會在四個介面,一組欄位收尾——說明編輯、檢視、呈現與功能如何在不建立第二套資料模型的情況下,讀取同一組使用中欄位。若想了解更多 FTS 策略細節,可停留在FTS5 用於標題;篩選勝出時改用全表掃描。
最後更新 2026-11-26
相關故事
- 插槽,而非空白頁
閱讀時間 6 分鐘
- CBF:結構化欄位離開記憶體的方式
閱讀時間 8 分鐘
- 標題用 FTS5;篩選勝出時走表掃描
閱讀時間 7 分鐘