安全模型
密钥体系、端到端加密与零信任设计。
SwarmDrop 的安全目标很直接:除了收发双方,没有任何一方能读到文件内容,包括引导节点和中继节点。
密钥体系
| 用途 | 算法 | 存放位置 |
|---|---|---|
| 设备身份 | Ed25519 密钥对 | 桌面:应用数据目录下仅本人可读的文件;移动:系统安全存储 |
| 配对邀请 | Ed25519 签名 + 128-bit capability | 邀请串本身,一次性消费 |
| 在途加密 | Noise(TCP / WebRTC)· TLS 1.3(QUIC) | 每条连接握手协商,仅内存 |
| 完整性校验 | BLAKE3(bao-tree 逐块验签) | 随每个数据块传输 |
设备私钥永不离开本机。移动端由系统安全存储托管(iOS Keychain、Android
EncryptedSharedPreferences);桌面端存放在应用数据目录下的 identity.json,unix 上权限为
0600(仅文件所有者可读写),形态与不设口令的 SSH 私钥一致——它防的是同一台机器上的
其他用户,不防以你的身份运行的其他进程。你可以在节点状态弹窗的诊断区看到并复制它的完整
路径,备份或换机迁移时需要它。
桌面端不用系统钥匙串,是因为本应用采用 ad-hoc 代码签名:macOS 的钥匙串按代码签名标识 授权,而 ad-hoc 签名的标识每次构建都会变,结果是每次启动都要点授权框、且「始终允许」 无法生效。
每条连接都要重新完成 Noise 握手、协商各自独立的临时会话密钥。
端到端加密
加密由传输层承担:两台设备之间的每条连接都是 Noise(或 QUIC 的 TLS 1.3)加密的, 双方的身份密钥在握手时互相鉴权——连上的是不是那台设备,由密码学保证,不靠自报。
中继节点只转发密文。 跨网时数据经 circuit relay v2 中转,而收发双方是在中继提供的字节 管道之上另行完成一次端到端握手的——中继手里没有任何密钥,解不开它转发的内容。 打洞成功时甚至不存在中继。
早期版本曾在传输层加密之上再叠一层应用层 XChaCha20-Poly1305 加密,已于 wire v2 移除。 原因是它防御的是同一批攻击者,却把密钥经同一条已加密信道分发——一个能读到密文的攻击者 必然也能读到密钥,属于自引用的冗余。加密应当放在职责所在的那一层,且只放一次。 完整推导见开发笔记《删掉应用层加密:加密应该在哪一层》。
完整性:收完之前每一块都可验证
文件的 BLAKE3 哈希在发送前算出,作为 bao-tree 的验证根。每个数据块附带一份 bao 证明, 接收端收一块验一块——不必等整个文件落地才发现被篡改或损坏,断点续传也不必"信任对端"。
验签粒度与传输块粒度相同——每传一块就能独立验一块,不多不少。而无论分块多大, bao 树根都恰好等于整个文件的标准 BLAKE3 哈希,所以校验值就是文件本身的指纹。
零信任
- 引导节点:只帮新节点加入 DHT,看不到传输内容。
- 中继节点:只转发密文,没有解密能力。
- 无遥测:不收集任何用户数据,不连分析后台。
配对的信任建立
配对用一次性签名邀请:发起方生成一条自包含的邀请链接(https://swarm-apps.github.io/SwarmDrop/p/#…),链接与二维码是它的
两种载体。邀请携带 Ed25519 签名、128-bit capability 和有效期,只能被消费一次。
签名覆盖邀请的全部字段——包括网络策略。这意味着「仅局域网」这类承诺不会被中间人篡改降级。
威胁边界
SwarmDrop 保护的是在途的传输内容与设备私钥。它不负责:
- 静态加密:文件在收发两端都以明文存放,SwarmDrop 不做 at-rest 加密——那是存储层 与磁盘加密(FileVault / BitLocker / LUKS)的职责。
- 对方设备本身是否可信(配对意味着你信任那台设备)。
- 本机操作系统账户已被攻破的情形(此时任何本地存储都不再是屏障)。