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 天待退休状态,期间任何设备可以撤销。

组成

设备、存放点、密钥

设备

持有仓库密钥、能读写明文的客户端。长期密钥对,人类可读名字,全量或部分角色。新设备用短码或二维码配对;没有旧设备在场时凭恢复密钥加入。

存放点

只需要写不可变对象、按名读取、按前缀列举、删除。对象内容寻址、只增不改,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