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

BIP-32 分层确定性钱包

从一个种子派生出一整棵密钥树:钱包只需备份一次,就可以按账户与用途分层生成无数地址,还能只分享某一支的公钥而不交出花费权。本 BIP 目前处于已部署状态。

一、档案卡

档案卡
编号BIP-32
标题Hierarchical Deterministic Wallets
作者Pieter Wuille <[email protected]>
指定日期2012-02-11
层级Applications(应用)
类型Informational(信息类)
状态Deployed(已部署)
阅读版https://bips.dev/32
官方原文https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki

二、放在哪一族

BIP-32 是确定性钱包族的地基。它定义了“种子 → 密钥树”这套派生机制本身,后来的一系列文档都建在它上面:

BIP-39:把种子写成助记词,让人能抄写与口述

BIP-43:给树的第一层加“用途”字段

BIP-44:多账户层级结构,规定币种、账户、内外部链的固定路径

再往后还有 BIP-49、BIP-84、BIP-86 等按地址类型分工的派生方案,用的都是 BIP-32 的树与扩展密钥。

文档分两部分:第一部分是密钥派生系统本身;第二部分是在这棵树上搭出的默认钱包结构。第二部分是建议性的,第一部分才是互通的关键。

三、它要解决什么

当时的参考客户端使用随机生成的密钥:为了避免每笔交易后都重新备份,默认预存 100 个备用密钥放进密钥池。即便如此,这类钱包仍有三个硬伤:

原文举的例子是网店:商家希望让网站服务器为每笔订单、每位顾客生成新收款地址,但绝不能把能花钱的私钥放在服务器上。用椭圆曲线数学,可以只给服务器算公钥的能力;再加上分层结构,服务器拿到的只是“对外收款”那一支,连找零地址那一支都看不到。

四、规则本身

4.1 扩展密钥:密钥加链码

每个密钥都附带额外的 256 位熵,称为链码(chain code,32 字节)。私钥加链码记作扩展私钥 (k, c),公钥加链码记作扩展公钥 (K, c),其中 K 是由 k 算出的公钥。对应的扩展公私钥共用同一条链码。

每个扩展密钥有 2 的 31 次方个普通子密钥和同样数量的硬化(hardened)子密钥:普通子密钥用索引 0 到 2 的 31 次方减 1,硬化子密钥用 2 的 31 次方到 2 的 32 次方减 1,写作 i 加下标 H。

4.2 子密钥派生(CKD)

派生用 HMAC-SHA512,链码作密钥:

逐级派生就得到密钥树,路径写作如 m/3H/2/5(m 为主密钥,M 为其扩展公钥版本)。叶子节点是实际使用的密钥,中间节点代表由它派生出的整组后代。

4.3 主密钥怎样从种子来

先取一段 128 到 512 位的种子(原文建议 256 位),计算 HMAC-SHA512(Key = "Bitcoin seed", Data = 种子),左半部分作主私钥,右半部分作主链码。

4.4 序列化:xprv 与 xpub

扩展密钥序列化为 78 字节:4 字节版本字节(主网公钥 0x0488B21E、私钥 0x0488ADE4;测试网另有取值)、1 字节深度、4 字节父密钥指纹(取公钥 Hash160 的前 32 位)、4 字节子编号、32 字节链码、33 字节密钥数据。再加 4 字节双重 SHA-256 校验和并做 Base58 编码,得到恰好 111 个字符的字符串,主网上分别以 xprv、xpub 开头。

4.5 默认钱包结构

钱包按账户组织,默认账户编号为 0。每个账户有两条链:外部链用于生成对外收款地址,内部链用于找零等不必对外沟通的用途。路径约定为:m/iH/0/k 是账户 i 外部链的第 k 个密钥对,m/iH/1/k 是内部链的第 k 个。

原文列出的典型用法包括:共享主扩展私钥实现整钱包共享;把各账户的扩展公钥交给审计方,让其看到全部收付而碰不到任何私钥;总部用主密钥统看各分支办公室的钱包;把某账户外部链的扩展公钥当作“超级地址”,反复收款又不易被关联;以及只给不安全的电商服务器一支外部链扩展公钥——服务器被攻破也偷不走钱。

4.6 安全要点

原文专门强调一条反直觉的性质:父扩展公钥加上任意一个由它派生的普通(非硬化)子私钥,就等价于知道了父扩展私钥,进而能推出该父密钥的全部后代私钥。因此扩展公钥必须比普通公钥更小心地保管,账户层要用硬化派生——这样单个账户或更下层私钥的泄露,才不会危及主密钥和其他账户。

五、谁必须动

普通持币人:备份方式变了:从“反复备份随机密钥池”变成“保管好一个种子 / 主密钥”。种子在,整棵树都能重建;种子丢了或泄露了,整棵树都受影响。

钱包开发者:要实现扩展密钥、CKD 派生、硬化与普通索引、序列化导入导出,并至少能导入一个扩展公钥或私钥、访问其直接后代。默认钱包结构是建议而非强制,但原文鼓励照做以保持兼容。

商家与服务器运营方:可以在服务器上只部署扩展公钥生成收款地址,私钥离线保管——这是本 BIP 最早描绘、后来被广泛采用的部署方式。

共识层与全节点:完全不动。BIP-32 是纯钱包侧的密钥管理方案,链上看到的仍是普通公钥与签名,节点无从也无需知道某个地址出自哪棵树。

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

状态为 Deployed,类型虽标为 Informational(信息类),其派生与序列化规则事实上已成为钱包互通的通用标准:xpub / xprv、路径记法、硬化标记,今天仍是各类钱包与工具的共同语言。具体账户结构由 BIP-44 等后续文档细化,种子的人类可读形式由 BIP-39 承担。

常见误读:

“xpub 只是公钥,公开它没有任何风险,随便发给谁都行。”

不对。原文的安全一节写得很明确:扩展公钥泄露首先是隐私泄露——对方能推出该支全部地址,看清你的收付全貌;更危险的是,若对方再拿到该支下任意一个普通子私钥,就能反推出父扩展私钥,接管整支密钥。xpub 要按“半个私钥”来保管,而不是按普通收款地址来随手分发。

七、延伸

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