WebRTC 点对点传文件的原理与安全边界
「点对点」不是玄学,它是浏览器内置的 WebRTC 能力:先交换连接信息,再做 NAT 穿透,最后在两端之间建一条加密的数据通道。
三步建立连接
- 信令:双方通过一个房间服务交换 SDP(媒体/数据能力描述)和 ICE 候选(我可能能被哪些地址找到)。这一步不含文件内容。
- 打洞:双方用 STUN 服务器知道自己对外的地址,然后同时向对方发包,让两边的 NAT 各开一个口子。
- 加密:通道建立后由 DTLS 加密,两端会显示同一个 8 位校验码(双方证书指纹的哈希),对一下就知道没有中间人。
为什么有的网络打不通
NAT 分几种。锥形 NAT 允许「先出后进」,打洞容易;对称 NAT 会给每个目标分配不同的端口,打洞基本失败——公司网、校园网、部分 4G/5G 常见这种。
还有一种情况:一方只有 IPv4、一方只有 IPv6,两个地址族之间无法直接配对,也会失败。
服务器能看到文件吗
直连时不能。服务器只转发 SDP/ICE 这类连接信息,数据面走的是两端之间的加密通道。
只有你主动点「改用中转」时,文件才会上传到 R2 再由对方下载;这条路径经过服务器,所以会明确提示,并支持传完立即删除。
安全边界要说清楚
- 通道是 DTLS 加密的,8 位校验码用于确认两端看到的证书一致,防中间人。
- 取件码是进入房间的凭据:知道码的人可以进入房间。请只发给要传文件的人,传完点「离开」换新码。
- 不建立账号、不保存传输历史;关掉页面,房间就结束。
三种候选类型
| 类型 | 含义 | 跨网络可用吗 |
|---|---|---|
| host | 本机网卡地址(局域网) | 基本不可用,浏览器还会用 mDNS 隐藏它 |
| srflx | 通过 STUN 拿到的公网映射 | 可用,是打洞的主力 |
| relay | TURN 中继 | 可用,但所有流量过服务器 |
一次连接的消息序列
发送方创建 offer(含 SDP)→ 接收方回 answer → 双方各自把收集到的 ICE 候选逐个发过去 → 双方用这些候选做连通性检查 → 选中的那一对开始传数据。
这些消息都走房间的 WebSocket,只有文本,不含文件内容。
为什么 8 位校验码够用
它不是用来防暴力破解的密码,而是让人眼比对两端看到的是不是同一对证书。中间人要让两端显示同一个码,需要同时伪造两边的指纹,这在 DTLS 握手中做不到。
真正的加密由 DTLS 完成;校验码只是一个可核对的「指纹摘要」。
和「上传下载」有什么不同
HTTP 上传是先把文件完整写到服务器,对方再去下载:好处是离线可用、可以续传、可以长期保存;坏处是上传那一步必须先完成,而且文件一定会落在别人的磁盘上。
点对点是两端同时在线、直接对流:少一次落盘、少一段等待,但要求双方在线,且网络允许直连。两种方式不是替代关系,是不同场景。
常见问题
- 为什么不做 TURN 中转加速?
- TURN 会让所有流量过服务器,成本和隐私代价都高,而且用户会误以为自己在直连。这里选择「打不通就明说」,把中转做成一个显式选项。
- 校验码是文件哈希吗?
- 不是,是连接证书的指纹哈希,用来确认没有中间人。文件完整性由 DTLS 保证。
- 公司网完全不能用吗?
- 直连大概率不行;可以换手机热点重试,或者使用中转。