CipherFS
開發中 · 未發布 · 格式可能變更

用戶端加密、無可信伺服器的多裝置檔案庫

檔案在離開你的裝置之前就已加密。裝置之間直接同步,也可以經由任何只會存取位元組的地方中轉:S3、本機目錄、由 iCloud 或 Dropbox 搬運的資料夾。它們都看不到檔名和內容,也不需要鎖或原子更新。

以 Rust 實作,提供 CLI、FUSE 掛載、Web 介面和 C / Python / Go 綁定。

存放點看到的

i/d7a1…/000412-9f3c…-18204
i/2b90…/000098-71e0…-6112
p/3f/3f8a…-6291456
p/c2/c2d4…-5833728
n/0007-e41b…-2097152
r/d7a1…-epoch3

裝置看到的

docs/
  contract-2026.pdf        2 個版本
  notes.md                 衝突 2
photos/
  2026-09/IMG_4471.heic    讀取時取得
projects/cipherfs/
  README.md
垃圾桶: old-drafts/ (14 個檔案)

左邊是物件名稱:裝置識別碼、序號、長度和密文雜湊。右邊是裝置解密後呈現的檔案樹,包括版本數、衝突和垃圾桶。兩邊之間沒有伺服器。

設計

它承諾什麼

用戶端加密

內容、檔名和敏感中繼資料在離開裝置前加密。讀取時驗證完整性,錯誤密碼、竄改和損壞都會明確失敗。金鑰和明文不會進入日誌或存放點。

可靠同步

離線修改在恢復連線後同步,中斷可以重試,重複傳輸不會重複執行或復活舊版本。並行修改依統一規則決定目前版本,其他版本全部保留。

大小檔案一視同仁

小檔案減少開銷,大檔案分塊、串流處理、依讀取範圍取得資料塊。使用者不需選擇模式,跨越大小門檻不改變語意。

核心與介接層分離

加密、檔案模型、儲存交易和同步規則屬於核心。CLI、掛載、Web 和語言綁定只做介接,不複製資料庫,不另訂規則。

完整索引,可選內容

每台裝置保留完整的共享索引。內容預設同步到每台裝置;手機或空間不足的電腦可宣告為部分裝置,只保留釘選目錄和最近讀過的內容。

無可信伺服器

裝置以 P2P 直連,存放點只存密文物件。歷史、垃圾桶和衝突是同一條共享版本鏈的不同視圖,所有裝置都看得到。裝置有獨立身分,可以被撤銷。

模型

歷史、垃圾桶和衝突是同一條鏈

每個檔案有穩定的身分,路徑只是屬性。每台裝置附加自己的簽章日誌,其他裝置驗證成員權限、雜湊鏈和因果相依後合併。刪除是一個 tombstone 版本,移動是改變路徑的版本,衝突是多個沒有因果先後的 head。

v1 notes.md 裝置 A 09-28 14:02 v2 notes.md 裝置 A 10-01 09:15 ← 歷史 v3 notes.md 裝置 B 10-03 22:40 ← head(目前) v3' notes.md 裝置 C 10-03 22:41 ← head(衝突) v4 父 = v3, v3' ← 任一裝置看到兩個 head 後寫入,衝突自動結束

目錄和掛載只呈現目前版本,不產生衝突副本檔案。版本只能由明確清除或隨索引同步的保留原則退役(預設 365 天),先進入 30 天待退役狀態,期間任何裝置都可以撤銷。

組成

裝置、存放點、金鑰

裝置

持有儲存庫金鑰、能讀寫明文的用戶端。長期金鑰對、人類可讀的名字、完整或部分角色。新裝置用短碼或 QR Code 配對;沒有既有裝置在場時憑復原金鑰加入。

存放點

只需要四種操作:寫入不可變物件、依名稱讀取、依前綴列舉、刪除。物件以內容定址、只增不改,以 4 到 8 MiB 打包。尚未完整到達的物件視為「未到達」而非「損壞」。

金鑰

內容金鑰依紀元衍生。撤銷一台裝置就開啟新紀元,新金鑰只封裝給剩餘的裝置。密碼只保護本機;忘記密碼時憑復原金鑰重設,裝置身分不變。

情境

把不常用的檔案移出 Mac 硬碟

一台常開的機器設為完整裝置,Mac 設為部分裝置並掛載。Mac 上只保留釘選目錄和最近讀取的內容,其餘在 Finder 裡照常列出,開啟時才從完整裝置或存放點取回,超出預算後自動釋放已確認存在於別處的內容。未同步的本機寫入和開啟中的檔案不會被釋放。

已在 macOS 27 與 FUSE-T 上實測:掛載點帶有 .metadata_never_index,排除 Time Machine,Finder 瀏覽全部目錄後快取位元組不變,離線讀取立即回報錯誤而不是卡住。

狀態

現在能發布嗎

還不能作為正式版發布。已確認的需求主體已實作並有逐項驗收證據,但格式和 API 仍允許變更,沒有第三方安全稽核,也從未做過相容性承諾。現在適合作者本人和少數願意接受格式變更的人試用。

以下是截至 2026 年 10 月 12 日的驗證結果。統計依各 feature 組合的實際執行次數計算。

驗證結果
主機 Rust 測試,預設 feature672 通過 / 0 失敗通過
主機 Rust 測試,全 feature700 通過 / 0 失敗通過
容器完整驗證 Rust754 通過 / 0 失敗 / 2 忽略通過
C 執行階段 / Python / Go race15 / 10 / 整包通過
前端建置、Web 冒煙測試24 項通過
真實 FUSE-T 部分裝置掛載與 Finder 瀏覽快取 54,288 → 54,288 B通過
需求驗收表R01–R62 逐項對應測試完成

尚未完成

上手

命令列

密碼從 CIPHERFS_PASSWORD 或互動輸入讀取;S3 憑證從環境變數讀取,不寫入共享索引。

cipherfs init --path ~/vault
cipherfs put --vault ~/vault --source ./notes.txt --target docs/notes.txt
cipherfs store add directory --vault ~/vault --dir ~/Library/CloudStorage/Dropbox/cfs
cipherfs sync directory --vault ~/vault --store-dir ~/Library/CloudStorage/Dropbox/cfs

cipherfs role set partial --vault ~/vault --read-cache-bytes 2147483648
cipherfs pin add --vault ~/vault --path docs
cipherfs mount --vault ~/vault --mount-point ~/CipherFS --background

cipherfs devices list --vault ~/vault
cipherfs safe-to-remove --vault ~/vault
cipherfs history --vault ~/vault --path docs/notes.txt
cipherfs export --vault ~/vault --target ~/plain-copy --history

Rust 應用程式使用 SyncedVault:put、put_from_reader、get、get_to_writer、get_range、delete、list。寫入成功代表本機已持久化,背景負責同步、重連和重試。記憶體用量與物件大小無關。

預設

演算法

用途演算法
內容 AEADXChaCha20-Poly1305(可選 AES-256-GCM、ChaCha20-Poly1305)
分塊FastCDC,min/avg/max 1 / 4 / 8 MiB,單元上限 16 MiB
內容定址BLAKE3
裝置身分ed25519 簽章,X25519 封裝,同時作為 P2P 節點識別碼
本機密碼Argon2id 封裝本機金鑰材料,不參與同步
傳輸QUIC(Iroh),存放點視需要使用 HTTPS