深入区块链——比特币的【HD钱包】BIP39生成助记词(第六讲)
导言
区块链(Blockchain)技术源于比特币,本质上其实是一个分布式的,不可篡改的数据库,具有可验证、可信任的特性。
本系列教程带你逐步深入理解区块链技术,并附带源码教程(主要使用PHP编写),但需要你对密码学原理、安全机制、共识算法、哈希算法有一定的认知。
教程源码:https://github.com/wenshunbiao/bitcoin-tutorial
正文
从HD钱包的创建方式可知,要创建一个HD钱包,我们必须首先有一个确定的512bit(64字节)的随机数种子。
如果用电脑生成一个64字节的随机数作为种子当然是可以的,但是恐怕谁也记不住。
如果自己想一个句子,例如bitcoin is awesome
,然后计算SHA-512获得这个64字节的种子,虽然是可行的,但是其安全性取决于自己想的句子到底有多随机。像bitcoin is awesome
本质上就是3个英文单词构成的随机数,长度太短,所以安全性非常差。
注意:不要自己挑选助记词,原因一是随机性太差,二是缺少校验。
同样索引的中文和英文生成的HD种子是不同的。各种语言的助记词定义在bip-0039-wordlists.md。
为了解决初始化种子的易用性问题,
BIP39规范提出了一种通过助记词来推算种子的算法:
通过九个步骤即可生成钱包助记词和种子:
> 步骤 1~6 生成助记词
> 最后把前六步生成的助记词转化为 BIP32 种子
【BIP39-生成助记词】
1.生成一个长度为 128~256 位 (bits) 的随机序列(熵);
2.取熵哈希后的前 n 位作为校验和 (n= 熵长度/32),就可以创造一个随机序列的校验和;
3.将校验和添加在随机序列(熵)的末尾;
4.将序列化分为包含11位的不同部分;
5.将每个包含11位不分的值与一个已经预先定义2048个单词的字典作对应;
6.生成的有顺序的单词组就是助记词。
步骤看下图:
在上面的例子中,我们选取了长度为128位的熵,来生成了有12个单词的助记码。在实际的应用中,熵的长度越长,校验码的长度和助记词的长度也会相应的增长。
下表展示了熵数据的大小和助记词的长度之间的关系:
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 |
步骤一:随机序列的长度为【128,160,192,224,256】。(熵一定是32的倍数,so熵是16进制数的序列)
步骤二:校验和的长度为【4,5,6,7,8】。(熵/32=校验和)
步骤三+步骤四:随机序列一定是11的倍数,平均划分为不同的11位倍数
步骤五:与2048个单词的预定义字典作对应
步骤六:生成助记词的数量:(熵+校验和)/ 11 = 助记词的数量
BIP39标准就是为了解决助记词的需求,通过随机生成12~24个容易记住的单词,单词序列通过 PBKDF2 与 HMAC-SHA512 函数创建出随机种子作为BIP32的种子。
根据助记词推算种子
根据助记词推算种子的算法是PBKDF2,使用的哈希函数是Hmac-SHA512,其中,输入是助记词的UTF-8编码,并设置Key为mnemonic+用户口令,循环2048次,得到最终的64字节种子。
从助记词算法可知,只要确定了助记词和口令,生成的HD种子就是确定的。
如果两个人的助记词相同,那么他们的HD种子也是相同的。这也意味着如果把助记词抄在纸上,一旦泄漏,HD种子就泄漏了。
如果在助记词的基础上设置了口令,那么只知道助记词,不知道口令,也是无法推算出HD种子的。
把助记词抄在纸上,口令记在脑子里,这样,泄漏了助记词也不会导致HD种子被泄漏,但要牢牢记住口令。
小结
BIP-39规范通过使用助记词+口令来生成HD钱包的种子,用户只需记忆助记词和口令即可随时恢复HD钱包。
丢失助记词或者丢失口令均会导致HD钱包丢失。