深入理解比特币系列(21): 比特币钱包技术

比特币钱包分为非确定性钱包及确定性钱包。前者早期采用过,目前主流的实现方式是后者。确定性钱包的核心是随机生成的种子,其优点是可以通过种子收回所有已经产生的私钥,所以只要在初始创建时做一个简单的备份就好了。并且种子也能够让使用者的私钥在钱包之间轻松的转移。本文将对确定性钱包中的助记码词汇(BIP-39)和HD钱包(BIP-32)做一介绍。

助记码词汇(BIP-39)

助记码词汇是英文单词序列代表(编码)用作种子对应所确定性钱包的随机数。单词的序列足以重新创建种子,并且从种子那里重新创造钱包以及所有私钥。在首次创建钱包时,带有助记码的,运行确定性钱包的钱包的应用程序将会向使用者展示一个12至24个词的顺序。单词的顺序就是钱包的备份。它也可以被用来恢复以及重新创造应用程序相同或者兼容的钱包的钥匙。助记码代码可以让使用者复制钱包更容易一些,因为它们相比较随机数字顺序来说,可以很容易地被读出来并且正确抄写。

BIP0039定义助记码和种子的创建过程如下:

1. 创造一个128到256位的随机顺序(熵);
2. 提出SHA256哈希前几位,就可以创造一个随机序列的校验和;
3. 把校验和添加在随机序列的尾部;
4. 把序列分解成11位的不同集合;
5. 将每一个11位值与预先定义的2048个单词字典做对应;
6. 生成的12-24个的单词组就是助记码;
7-9. 通过密钥延伸函数PBKDF2,使用2048次哈希来计算产生一个512位的值,这值就是种子。

1-6步的助记码词汇生成图示如下:

Generating entropy and encoding as mnemonic words

下表显示了熵的大小和助记码词汇长度之间的关系:

Entropy (bits) Checksum (bits) Entropy + checksum (bits) Mnemonic length (words)
128 4 132 12
160 5 165 15
192 6 198 18
224 7 231 21
256 8 264 24

7-9步的种子生成图示如下:

From mnemonic to seed

下面给出一些种子的生成案例:

Entropy input (128 bits) 0c1e24e5917779d297e14d45f14e1a1a
Mnemonic (12 words) army van defense carry jealous true garbage claim echo media make crunch
Passphrase (none)
Seed (512 bits) 5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4c67196f57c39 a88b76373733891bfaba16ed27a813ceed498804c0570
Entropy input (128 bits) 0c1e24e5917779d297e14d45f14e1a1a
Mnemonic (12 words) army van defense carry jealous true garbage claim echo media make crunch
Passphrase SuperDuperSecret
Seed (512 bits) 3b5df16df2157104cfdd22830162a5e170c0161653e3afe6c88defeefb0818c793dbb28ab3ab091897d0 715861dc8a18358f80b79d49acf64142ae57037d1d54
Entropy input (256 bits) 2041546864449caff939d32d574753fe684d3c947c3346713dd8423e74abcf8c
Mnemonic (24 words) cake apple borrow silk endorse fitness top denial coil riot stay wolf luggage oxygen faint major edit measure invite love trap field dilemma oblige
Passphrase (none)
Seed (512 bits) 3269bce2674acbd188d4f120072b13b088a0ecf87c6e4cae41657a0bb78f5315b33b3a04356e53d062e5 5f1e0deaa082df8d487381379df848a6ad7e98798404

HD钱包(BIP-32/BIP-44)

确定性钱包被开发成更容易从单个“种子”中生成许多关键的密钥。最高级的确定性钱包形式是通过BIP0032标准生成的分层确定性钱包,也被称为HD钱包。HD钱包从种子生成主密钥,从主钥匙又可以生成子钥匙的序列,是一种树状结构。如下图所示:

HD wallet

HD钱包有两个主要的优点。第一,树状结构可以被用来表达额外的组织含义。比如,一个特定分支的子密钥可以被用来接收交易收入,而另一个分支的子密钥用来负责支付花费。在企业环境中,不同分支的密钥可以用来分配给不同的子公司、部门等。

HD钱包的第二个好处就是它可以去建立一个公钥序列而无需访问相对应的私钥。这将允许HD钱包在不安全的服务器中没有私钥的情况下可以使用公钥。

HD钱包主密钥生成流程如下图所示:

HDWalletFromRootSeed

主私钥(Master Private Key)可以通过之前的密码学基础教程计算出主公钥(Master Public Key)。主链码(Master Chain Code)的作用是用来生成子密钥。

由父密钥,父链码及索引号通过HMAC-SHA512运算可以生成子密钥及子链码。这里父密钥可以根据使用场景选择父私钥或者父公钥。

由父公钥推算子密钥的方式称作一般衍生(normal derivation)。只能计算出其子节点及其衍生节点的所有子公钥。这在某种程度上确保了在第三方服务器上的安全性。但是,因为扩展公钥(即父公钥+父链码)包含有父链码,如果子私钥被泄漏的话,父链码就可以被用来衍生所有的其他子私钥。更糟糕的是,子私钥与父链码可以用来推断父私钥。

另一种推算密钥的方式由父私钥来计算,也称为强化衍生(hardened derivation)。可以得到完整的子节点及其衍生节点的所有私钥和公钥。由强化衍生得到的子私钥以及链码与使用一般衍生得到的结果完全不同。得到的密钥“分支”可以被用来生产不易被攻击的扩展公钥,因为它所含的链码无法被用来窃取任何私钥。

Andreas的推荐方法是:主密钥所衍生的第一层级子密匙最好使用强化衍生。之后的层级可采用一般衍生。