文件交换系统构思
本文由早期草稿整理扩展。当前是可落地的设计构思,尚未对应某一开源实现;算法与流程已对齐表述,并补上威胁模型、密钥管理与失败恢复。
1. 目标与非目标
1.1 想解决什么
在不依赖双方同时在线的专用中继服务器、也不希望明文经过「自己可控的中心存储」的前提下,完成单文件的点对点交换:
- 载荷只以密文形式出现在多个互不相关的匿名/半匿名中转站;
- 密钥与下载线索走另一条信令通道(草稿里用 note.ms 一类可写即焚页面);
- 加解密与密钥保管尽量落在双方各自的小型硬件设备上,减少在通用 PC 上暴露明文与主密钥的时间。
1.2 明确不做
| 非目标 | 说明 |
|---|---|
| 大流量同步盘 | 不做多文件目录同步,单次任务 = 一个文件 |
| 完美匿名对抗国家级对手 | 中转站与信令仍可能被关联分析 |
| 实时双向聊天 | 只做文件投递 + 状态机 |
| 中心化账号体系 | 不引入统一用户 ID 服务 |
1.3 设计原则
- 密钥与载荷分离:密文分卷上中转站,密钥材料只走信令。
- 多层不同算法:对称层叠加 + 分卷,单点泄露不至于「一键还原」。
- 分卷分散托管:三个分卷三个站,少一卷则无法解压还原。
- 短时信令:note 页写入后尽快取走清空,降低信令驻留。
- 状态可观测:收发 UI 用阶段条表达进度,便于人工值守。
2. 角色与组件
┌─────────────┐ 信令(加密元数据) ┌─────────────┐
│ 设备 A │ ──── note 路径 / 轮询 ──────────► │ 设备 B │
│ (发送侧) │ │ (接收侧) │
└──────┬──────┘ └──────▲──────┘
│ 密文分卷 ×3 │ 下载分卷 ×3
▼ │
中转站1 / 中转站2 / 中转站3 ────────────────────────────┘
| 组件 | 职责 |
|---|---|
| 硬件设备 | 本地生成/保管密钥、加解密、分卷、上传下载、轮询信令 |
| 信令面 | 存放 RSA 加密后的元数据 JSON(密钥、哈希、链接) |
| 载荷面 | 三个互异的匿名文件中转,各存一个 7z 分卷 |
| 控制 UI | 展示发送/接收阶段(可跑在设备 Web UI 或配对 App) |
设备对:预先绑定的一对设备(A↔B)。可扩展多对,用「设备对号」区分。
3. 威胁模型(简要)
| 对手能力 | 假设 | 本方案应对思路 |
|---|---|---|
| 单个中转站运营方 | 可见一个分卷密文 | 缺另外两卷 + 外层密钥,无法还原 |
| 信令页被第三方先读到 | 可见 RSA 密文 | 无私钥则无法解元数据 |
| 网络窃听 | 可见 HTTPS/中转流量 | 载荷已是多层密文 |
| 设备被物理拿走 | 可能有密钥与明文 | 需设备 PIN/安全元件;明文尽快删 |
| 全球被动关联 | 时间与体量关联三站+信令 | 降风险:随机延迟、体积填充、多通道;不能指望绝对抗关联 |
| note 类服务被封/投毒 | 可用性、完整性 | 双信令备份、元数据带 HMAC/签名 |
不防:两端设备都被植入木马;用户主动把明文再拷到不可信电脑且长期存放。
4. 密钥与标识
4.1 非对称密钥(长期,按设备对)
草稿表述易混,这里定成清晰模型:
- 每台设备持有自己的 RSA-4096(或 X25519 + 签名用 Ed25519,实现阶段可升级)密钥对。
- 发往 B 的元数据:用 B 的公钥加密(只有 B 能解)。
- 可选:元数据外层再由 A 签名,B 验签防伪造信令。
若坚持「RSA A 组 / B 组」双组密钥,建议语义固定为:
| 名称 | 含义 |
|---|---|
| 设备身份密钥 | 长期,出厂/初始化生成,私钥不出安全芯片 |
| 会话封装 | 每次发送用接收方身份公钥封装对称会话密钥 |
4.2 对称会话密钥(每次发送临时生成)
每次任务独立生成三把互不复用的随机密钥:
| 密钥 | 算法 | 长度 | 用途 |
|---|---|---|---|
| (K_1) | ChaCha20-Poly1305(AEAD) | 256-bit | 明文 → *.secretdata1 |
| (K_2) | SM4-GCM(或 SM4-CTR+HMAC) | 128-bit | secretdata1 → *.secretdata2 |
| (K_3) | 7z 加密(AES-256,p7zip 实际能力) | ≥256-bit 口令材料 | 分卷压缩包 |
与草稿 UI 对齐说明:早期草稿里「流程写 ChaCha20 / 界面写 AES256」不一致。实现上建议:
- 内容加密层明确用 ChaCha20-Poly1305 + SM4-AEAD;
- 分卷层使用 7z 自带 AES-256;
- UI 文案与真实算法一致,避免运维误判。
4.3 随机数与「公共熵」
草稿:用 BTC 现价 + ETH 持持仓等作种子,欧意/火币双备。
更稳妥的做法:
- 主熵:设备 TRNG /
getrandom/ 安全芯片。 - 辅助熵(可选):多源行情 API 的哈希混入,抗「单一 RNG 实现烂」——不能替代系统 CSPRNG。
- 盐
S:设备对初始化时协商或预置,写入安全存储。
通道路径示例:
path = hex( SHA256( date_utc + channel_id + pair_id + S ) )
信令 URL = https://note.ms/{path} # 或自建等价「可写短文本」服务
建议用 SHA-256 而非 MD5;日期用 UTC 并约定切换点(如每日 00:00 UTC),避免双方时区不一致。
4.4 通道
- 每对设备可配置多个 channel_id(业务隔离:合同、影像、应急…)。
- 设备循环轮询当日路径;可同时监听「今日 + 昨日」防止跨日边界丢信令。
5. 元数据格式(信令明文 JSON)
RSA/ECIES 封装前的明文示例:
{
"v": 1,
"pair_id": "AB-001",
"channel_id": 3,
"task_id": "01J…",
"filename": "report.pdf",
"filesize": 10485760,
"created_at": "2026-07-20T12:00:00Z",
"k1": "<base64>",
"k2": "<base64>",
"k3": "<base64-or-passphrase>",
"parts": [
{
"idx": 1,
"sha256": "…",
"url": "https://mirror-a.example/…",
"expires_at": "2026-07-21T12:00:00Z"
},
{ "idx": 2, "sha256": "…", "url": "…", "expires_at": "…" },
{ "idx": 3, "sha256": "…", "url": "…", "expires_at": "…" }
],
"note": "optional human hint"
}
封装:ciphertext = RSA-OAEP(B_pub, json) 或「随机 DEK + RSA 封 DEK」以支持更长 JSON。
信令页只写密文;B 取走后立即清空。
6. 发送流程(设备 A → B)
6.1 步骤
- 用户在 A 侧选定单个文件,创建任务
task_id。 - 设备生成 (K_1,K_2,K_3)。
- 一层:ChaCha20-Poly1305 加密明文 →
file.secretdata1。 - 二层:SM4-GCM 加密 →
file.secretdata2。 - 三层:p7zip/7z 使用 (K_3) 加密并切成 3 个分卷(体积尽量接近,可填充对齐)。
- 对每个分卷计算 SHA-256。
- 将分卷 分别上传 到三个不同中转站,得到
url1..3(失败则换站重试)。 - 组装元数据 JSON,用 B 的公钥加密,写入当日信令路径。
- 本地按策略删除中间态;仅保留任务日志(可无密钥)。
6.2 发送侧 UI 阶段(与算法一致)
| 阶段 | 显示文案 |
|---|---|
| 1 | 发送任务创建 |
| 2 | 一级加密(ChaCha20-Poly1305) |
| 3 | 二级加密(SM4-GCM) |
| 4 | 三级加密分卷(7z AES-256) |
| 5–7 | 上传分卷 1 / 2 / 3 |
| 8 | 信令已发布,等待对方拉取 |
| 9 | 对方已取信令 / 分卷已被下载(若中转可探测) |
| 10 | 任务完成或超时失败 |
「已被下载」依赖中转站是否提供次数/状态;没有则只能靠 B 回执信令(可选 ACK 通道)。
7. 接收流程(设备 B)
- 轮询信令路径,发现非空 → 先下载密文再清空页面(防他人二次读)。
- 用 B 私钥解密元数据;校验
pair_id/ 签名 / 时间窗。 - 并行下载三个分卷;逐个校验 SHA-256,失败则有限次重试或换镜像字段(若元数据带备用 URL)。
- 用 (K_3) 解 7z 合并 →
secretdata2。 - (K_2) 解 SM4 →
secretdata1。 - (K_1) 解 ChaCha20 → 明文,存设备保险区。
- 擦除分卷与中间文件;通知用户「可取回」。
7.1 接收侧 UI 阶段
| 阶段 | 显示文案 |
|---|---|
| 1 | 接收任务创建 |
| 2–4 | 下载分卷 1 / 2 / 3 |
| 5 | 分卷校验通过,合并解密(7z) |
| 6 | 二级解密(SM4-GCM) |
| 7 | 一级解密(ChaCha20-Poly1305) |
| 8 | 清除过程文件 |
| 9 | 等待用户下载到可信终端 |
| 10 | 用户已取走 / 本地副本已按策略销毁 |
8. 失败恢复与边界情况
| 情况 | 处理 |
|---|---|
| 某一中转上传失败 | 自动换提供商;三站都失败则任务失败,不写信令 |
| 信令写入失败 | 载荷可先不删,指数退避重试;超时则删分卷防孤儿密文长期挂公网 |
| 跨日路径不一致 | 同时听「UTC 今日+昨日」 |
| 分卷哈希不符 | 重下;仍失败则信令标 failed,A 可重发新任务(新密钥) |
| 中转提前删档 | 任务失败;可要求 A 在有效期内重传 |
| 元数据被串改 | 公钥加密下攻击者难精确定制;加签名后可直接拒收 |
| 大文件 | 单文件上限(如 2GB)由设备磁盘与中转限制决定;超时与断点续传按中转能力实现 |
重发:永远生成新的 (K_1..K_3) 与 task_id,禁止复用会话密钥。
9. 中转站与信令选型建议
9.1 载荷中转
- 条件:匿名/免登录、直链下载、尽量支持 HTTPS、有过期时间。
- 策略:三个不同运营主体;避免同一集团 CDN。
- 上传出口可用不同网络路径(降低「同一 IP 传三站」的简单关联)。
9.2 信令
- 草稿:note.ms 类「猜路径即可读写」——实现简单,但可用性与投毒是风险。
- 增强选项:
- 自建短 TTL 的 KV(Cloudflare Workers + 鉴权);
- 双写两个信令后端,元数据相同;
- 路径仍由日期+通道+盐派生,不把真实 pair 写进 URL。
10. 安全加固清单
- 私钥与 (K_i) 仅在设备安全元件/加密分区使用,UI 进程不落盘明文密钥。
- AEAD 必用(ChaCha20-Poly1305、SM4-GCM),避免「只加密不校验」。
- 明文与中间文件:任务结束
shred/安全擦除。 - 任务日志默认不含密钥与完整 URL,或单独加密审计库。
- 速率限制:防信令路径被扫(盐长度足够,如 128-bit)。
- 固件签名升级;调试口出厂关闭。
- 法律与合规:匿名中转与跨境传输需按使用地区自行评估。
11. 实现分期(从构思到原型)
| 阶段 | 交付 |
|---|---|
| P0 | Linux 上 CLI:本地三层加密 + 7z 分卷 + 手动上传 + RSA 封 JSON |
| P1 | 接入 2~3 个中转 API + note/自建信令轮询 |
| P2 | 设备镜像(ARM 小主机)、Web UI 状态机、双日路径 |
| P3 | 安全芯片存钥、ACK 回执通道、多通道 QoS、可观测指标 |
技术栈示例(无强制):Rust/Go 做加解密与状态机;7z 调 7zz;硬件用带 eMMC 的 ARM + 可选 TPM。
12. 流程总览(对照表)
| 步骤 | 发送方 A | 接收方 B |
|---|---|---|
| 1 | 选文件,生成会话密钥 | 轮询信令 |
| 2 | ChaCha20 加密 | 取信令并清空 |
| 3 | SM4 加密 | RSA 解密元数据 |
| 4 | 7z 加密分卷 ×3 | 下载分卷并校验哈希 |
| 5 | 分上传三站 | 7z → SM4 → ChaCha20 解密 |
| 6 | RSA 封元数据写信令 | 擦除中间文件,用户取回 |
13. 开放问题(后续可写专题)
- 是否引入邮筒模式(A 离线后 B 才上线的持久邮箱,但仍无明文服务器)?
- 三人以上群组如何做信封(多公钥封装同一 DEK)?
- 中转站 API 频繁变更时的「驱动插件化」?
- 与「家用存储 / Johnny.Decimal」归档流程如何衔接(收件后自动入库分类)?
修订说明
| 项 | 处理 |
|---|---|
| 原文 | 点对点收发步骤草稿,算法与 UI 表述不一致 |
| 补全 | 威胁模型、密钥语义、JSON 元数据、失败恢复、分期实现 |
| 修正 | 统一 ChaCha20 / SM4 / 7z-AES 与界面文案;MD5→SHA-256;RSA 方向改为「接收方公钥加密」 |
| 定位 | 设计构思文,非已上线产品说明书 |
