现在我们开始逐个深入了解这些比特币钱包所使用的重要的行业标准。

5.2.1 助记词(BIP-39)

助记词是表示(编码)随机数的一组有序的英文单词,用作生成确定性钱包的种子。这些有序单词足以重建种子,并且从种子重新创建钱包以及所有派生的密钥。使用助记词实现确定性钱包的应用会在首次创建钱包时,向使用者展示一个12至24个有序的单词。这些有序单词就是钱包的备份,就可以用来恢复以及重建相同或兼容钱包应用程序的密钥。与随机数序列比较,助记词可以让使用者备份钱包更容易一些,因为更容易阅读和正确抄写。

提示 助记词经常与“脑钱包”混淆。 他们不一样。主要区别在于脑钱包包含用户选择的单词,而助记词是由钱包随机创建呈现给用户的。 这个重要的区别使助记词更加安全,因为人类的随机数来源还是很贫乏的。

助记词定义在比特币BIP-39中(参见”附录 比特币改进协议”)。需要注意的是,BIP-39是助记词的标准实施方案。还有另外一个标准,使用一组不同的单词,早于BIP-39由Electrum钱包使用。 BIP-39由Trezor硬件钱包的母公司提出,与Electrum的实施不兼容。 其实,BIP-39现在已经通过数十个可互操作的实施获得了广泛的行业支持,已被视为事实上的行业标准。

BIP-39定义了助记词和种子的创建,我们在这里总结为九个步骤。 为了清楚起见,整个过程分为两部分:

1-6步见5.2.2创建助记词,7-9步见5.2.3从助记词到种子。

5.2.2创建助记词

助记词是由钱包使用BIP-39中定义的标准化过程自动生成的。 钱包从熵源开始,增加校验和,然后将熵映射到单词列表:
1、创建一个128到256位的随机序列(熵)。
2、提取SHA256哈希的第一(熵长/ 32)位,创造随机序列的校验和。
3、将校验和添加到随机序列的末尾。
4、将序列拆分为11位长度的多个段。
5、将每个11位值映射为有2048个单词的预定义字典中的一个单词。
6、生成的有顺序的单词组就是助记码。

5.2_钱包技术细节 - 图1

图5-6表示生成熵和编码作为助记词

图5-6 熵的产生和助记词的编码

表5-2表示了熵数据的大小和助记词的长度之间的关系。

表5-2助记词:熵及助记词长度

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

5.2.3从助记词生成种子

助记词表示长度为128至256位的熵。 通过使用密钥延伸函数PBKDF2,熵被用于导出更长的(512位)种子。产生的种子用于构建确定性钱包并导出密钥。

密钥延伸函数有两个参数:助记词和盐(salt)。 密钥延伸函数中盐的目的是增加构建暴力攻击使用的查找表的难度。 在BIP-39标准中,盐还有另一目的,引入密码口令(passphrase),作为保护种子的附加安全因素,我们将在BIP-39可选密码口令章节详细描述。

创建助记词之后的7-9步是:
7、PBKDF2密钥延伸函数的第一个参数是从步骤6生成的助记词。
8、PBKDF2密钥延伸函数的第二个参数是盐。 由字符串常数“mnemonic”与可选的用户提供的密码口令一起组成。
9、PBKDF2使用HMAC-SHA512算法,使用2048次哈希来延伸助记词和盐参数,产生一个512位的值作为其最终输出。 这个512位的值就是种子。

图5-7显示了从助记词如何生成种子
5.2_钱包技术细节 - 图2

图5-7 从助记词到种子

提示 密钥延伸函数,使用2048次哈希是一种非常有效的保护,可以防止对助记词或密码口令的暴力攻击。 它使得攻击尝试非常昂贵(从计算的角度),需要尝试超过几千个密码和助记词组合,而这样可能产生的种子的数量是巨大的(25122^{512})。

表5-3、5-4和表5-5展示了一些助记码的例子和它所生成的种子(有的带密码口令,有的不带)。

表5-3 128位熵助记词,没有密码口令产生的种子Entropy input (128 bits)|0c1e24e5917779d297e14d45f14e1a1a-|-Mnemonic (12 words)|army van defense carry jealous true garbage claim echo media make crunchPassphrase|(none)Seed (512 bits)|5b56c417303faa3fcba7e57400e120a0ca83ec5a4fc9ffba757fbe63fbd77a89a1a3be4c67196f57c39 a88b76373733891bfaba16ed27a813ceed498804c0570

表5-4 128位熵助记词,有密码口令产生的种子Entropy input (128 bits)|0c1e24e5917779d297e14d45f14e1a1a-|-Mnemonic (12 words)|army van defense carry jealous true garbage claim echo media make crunchPassphrase|SuperDuperSecretSeed (512 bits)|3b5df16df2157104cfdd22830162a5e170c0161653e3afe6c88defeefb0818c793dbb28ab3ab091897d0 715861dc8a18358f80b79d49acf64142ae57037d1d54

表5-5 256位熵助记词,没有密码口令产生的种子

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

5.2.4 BIP-39中的可选密码口令

BIP-39标准允许在推导种子时使用可选的密码口令。 如果没有使用密码口令,助记词是用由常量字符串“mnemonic”构成的盐进行延伸,从任何给定的助记词产生一个特定的512位种子。 如果使用密码短语,密钥延伸函数使用同样的助记词也会产生不同的种子。事实上,使用同一个助记词,每一个可能的密码口令都会导致不同的种子。 基本上没有“错误”的密码口令, 所有密码口令都是有效的,它们都会导致不同的种子,形成一大批未初始化的钱包。这些钱包数量非常之多(2512),根本不可能使用暴力破解或随机猜测。

提示 BIP-39中没有“错误的”密码口令。 每个密码都会导致一些钱包,只是未使用的钱包是空的。

可选密码口令带来两个重要功能:

  • (存储在大脑中的)密码口令成为第二重保护,使得仅有助记词是不够的,避免了助记词备份被盗取后利用。
  • 起到掩人耳目的效果或“胁迫钱包”,把选定的密码口令指向有小额资金的钱包,分散攻击者注意力,使其不再关注拥有大额资金的“真实”钱包。
    然而,需要注意的是,使用密码口令也会引起丢失的风险:
  • 如果钱包所有者无行为能力或死亡,没有人知道密码,种子就是无用的,所有存储在钱包中的资金都将永远丢失。
  • 相反,如果所有者将密码口令与种子备份在相同的地方,则失去第二重保护的目的。

虽然密码口令非常有用,但考虑到钱包拥有者幸存的可能性,以及允许其家人收回加密货币财产,密码口令只能与精心规划的备份和恢复过程结合使用。

5.2.5 使用助记词

BIP-39作为函数库实施,支持多种编程语言:

python-mnemonic

SatoshiLabs团队提出了BIP-39的Python标准参考实现

bitcoinjs/bip39

BIP-39的JavaScript实现是流行的bitcoinJS框架的一部分。

libbitcoin/mnemonic

BIP-39的C++实现是流行的Libbitcoin框架的一部分。

还有一个BIP-39在独立的网页中实现的生成器,非常适合用于测试和实验。图5-8展示一个独立的网页,可以生成助记词、种子和扩展私钥。

5.2_钱包技术细节 - 图3

图5-8 独立的网页BIP-39生成器

BIP-39生成器可以在线或离线使用,可以使用这个在线地址