协议演进 / BIP/比特币改进提案 / BIP-151

BIP-151 对等通信加密

用临时 ECDH 密钥为选定的节点连接协商对称加密,使 P2P 流量可加密传输并能检出中间人篡改。本 BIP 目前处于已关闭状态。

一、档案卡

档案卡
编号BIP-151
标题Peer-to-Peer Communication Encryption
作者Jonas Schnelli <[email protected]>
指定日期2016-03-23
层级Peer Services(对等服务)
类型Specification(规范类)
状态Closed(已关闭)
接替文档Proposed-Replacement: BIP-324
阅读版https://bips.dev/151
官方原文https://github.com/bitcoin/bips/blob/master/bip-0151.mediawiki

二、放在哪一族

P2P 网络隐私族里管“加密”的那一篇。它有一篇直接的下游与一个正式的后继:

BIP-150:对等节点认证。认证必须建立在加密通道之上,用的正是本篇协商出的会话 ID;本篇只管把通道变密文,管不了“对面是谁”。

BIP-324:v2 P2P 加密传输协议。本篇档案序言明确记有 Proposed-Replacement: 324——本篇的接替文档。加密节点流量这件事,最终是沿着 324 那套设计落地的,不是沿着本篇。

读本篇的价值,在于看清 2016 年这套方案的设计取向:机会性、按连接选择、只加密选定的一部分对等连接,而不是把全网流量一刀切地改掉。

三、它要解决什么

原文的出发点:比特币节点之间的通信在当时完全不加密。由此带来两类问题:

原文也坦承边界:即便加密,报文的大小、发送间隔等特征仍在,按流量特征分析通信类型依然可能;比特币的信任模型也让这类风险在多数场景下不算致命——但“能显著抬高针对性分析的成本”本身就是目标。

已有的替代办法——VPN、Tor、stunnel、curveCP 等更低层级的加密机制——对 SPV 节点与常见的 DHCP/NAT 环境并不实用,搭建门槛也高。本篇要给出的,是一个节点软件内建、上手成本低的加密选项,且只加密选定的一部分远端节点连接。

四、规则本身

4.1 总则:双向各自协商

4.2 密钥推导:ECDH + HKDF

双方各自生成临时(ephemeral)会话密钥对,交换公钥后用 ECDH 算出共享秘密,再用 HKDF(RFC 5869,哈希为 SHA256)推导:

分工上,K_1 只用来加密报文的长度字段,避免从明文长度泄露消息大小;K_2 与 Poly1305 配合构成 AEAD(带认证的加密)来保护正文。

4.3 握手消息:encinit 与 encack

请求方生成临时会话密钥对,发送 encinit 消息,内含:

应答方以 encack 回应,内含自己的临时公钥(33 字节);至此该方向的共享秘密即可算出。随后反方向必须再做一次同样的 encinit/encack,且第二个 encinit 必须使用相同的密码类型;第二次 encack 之前到达的未加密消息一律忽略。双向握手全部完成之后,线路必须切换为加密消息结构;此后再收到明文消息,应终止连接。

所用套件 ChaCha20-Poly1305 是 OpenSSH 的同名方案:ChaCha20 负责流加密,Poly1305 提供一次性消息认证。原文还引了一条性能判断:ChaCha20-Poly1305 的优化实现通常很快,按 Pieter Wuille 的初步分析,每字节的 CPU 开销甚至低于当时未加密格式所用的 SHA256。

4.4 加密消息结构

加密后的报文不再带 4 字节的网络魔数(network magic),结构为:

随之而来的变化:原格式的 4 字节 SHA256 校验和不再需要(AEAD 已提供完整性);双方要各自跟踪已发消息的序号(uint32,可在 2^32−1 后回绕到零),用来拼出 64 位的对称密码 IV;解密后的明文仍是原有的一条或多条“命令 + 长度 + 载荷”消息,段数不显式声明。原文也专门提醒:4 字节长度字段理论上会要求高达 4 GiB 的消息缓冲,必须谨慎处理,且不得在认证成功之前就处理报文内容。

4.5 重新换钥(Re-Keying)

应答方可以用一条内容为 33 字节零的 encack 通知对方换钥,此后消息改用下一把对称密钥:新密钥 = SHA256(SHA256(session_id || 旧对称密钥))。换钥间隔属于节点策略,但最短不得少于 10 秒;且每发送或接收 1 GB 数据之后必须换钥(此条按 RFC 4253 对 SSH 传输的建议)。

4.6 明确不管的事:身份

原文明说本篇的风险所在:加密协商不包含任何身份认证,无法防范协商阶段的中间人攻击。对面究竟是谁,要由另一篇文档(即 BIP-150)在加密通道之上再解决。

兼容性方面,本篇向后兼容:不支持的节点会忽略 encinit 消息。

五、谁必须动

普通持币人:无直接关系。不改地址、不改交易、不上链;影响的只是节点之间线路上的字节形态。

钱包开发者:只有直连 P2P 网络的轻钱包才需要实现 encinit/encack 握手与 ChaCha20-Poly1305 加解密;通过节点 RPC 或服务商接口同步的钱包不涉及。

全节点与矿工:自愿实现。节点需要能响应加密请求、双向协商、维护序号与换钥;不实现的节点照常以明文与他人通信,对方也不得因此断开。

共识层:完全不触碰。本篇是传输层选项,加密与否不影响任何区块与交易的有效性判定。

六、现在算不算数,以及一个常见误读

状态为 Closed(已关闭),且档案序言已注明 Proposed-Replacement 为 BIP-324。也就是说,本篇这套“encinit/encack + ChaCha20-Poly1305”的具体设计没有成为节点间的通行标准;“给 P2P 流量加密”这个问题本身,则由接替它的 v2 加密传输协议以另一套方案承接。提案评论摘要在序言中记为“有争议;有人推荐,也有人不鼓励(Controversial)”,本页如实转述。

常见误读:

“BIP-151 加密之后,节点通信就既私密又可信了。”

只对一半。按原文,它提供的是保密性与完整性:窃听者看不懂、篡改会被 AEAD 的标签检出。但它明确不做身份认证——你加密通话的对象可能正是中间人本人。把“加密”直接等同于“对方可信”,恰恰是原文在风险一节里点名要防的误会。

七、延伸

本页内容整理自 bitcoin/bips 仓库与 bips.dev,事实已与仓库核对;解读仅供学习参考。