1. 首页 > 创业 > 故事

深入浅出 HD 钱包基本原理

讲到这里,HD 钱包的基本原理已经都理清了,但是开篇提到的助记词是咋回事儿呢?

互联网发展了 20 多年,所有的互联网用户都熟悉了账户要输入密码的同时,生成、设置、记住密码对人来来说却变的很难,因为为了安全需要设置很复杂的密码,但是复杂的密码却不是那么容易记住。区块链钱包管理的私钥可以认为是随机生成的密码,有没有办法让这个密码变的更加用户友好呢?BIP39 提出的助记词机制就很好的解决了这个问题,让钱包私钥(对 HD 钱包来说就是种子)在安全性方面不打折扣,但是更容易识记。BIP39 主要描述了两个过程:· 根据随机数生成助记词的流程· 根据助记词推导 HD 钱包种子的流程

有个广泛流传的误解说助记词是随机生成的,实际上助记词并不是随机生成的,而是随机生成的种子的一种呈现方式。助记词谈到是怎么生成的呢?整个过程如下图:

· 生成 128 位的随机数,这个随机数在 BIP29 中叫做熵(Entropy,简写为 ENT);· 对随机数做 SHA256,取前 4 位为校验码(Checksum);· 把步骤 1、2 中的结果拼接得到 132 位的结果,然后分割成 12 个长度为 11 位的串;· 将 12 个串转化为十进制数字去此表中查找对应的单词;· 把查找到的单词按顺序拼接起来构成助记词;整个过程的代码实现如下:

function generateMnemonic(strength, rng, wordlist) { strength=strength || 128; if (strength % 32 !==0) throw new TypeError(INVALID_ENTROPY); rng=rng || randomBytes; return entropyToMnemonic(rng(strength / 8), wordlist);}function entropyToMnemonic(entropy, wordlist) { if (!Buffer.isBuffer(entropy)) entropy=Buffer.from(entropy, ‘hex’); wordlist=wordlist || DEFAULT_WORDLIST; var entropyBits=bytesToBinary([].slice.call(entropy)); var checksumBits=deriveChecksumBits(entropy); var bits=entropyBits + checksumBits; var chunks=bits.match(/(.{1,11})/g); var words=chunks.map(function(binary) { var index=binaryToByte(binary); return wordlist[index]; }); return wordlist===JAPANESE_WORDLIST ? words.join(‘ ’) : words.join(‘ ‘);}

在助记词生成过程中,不同长度的随机数所需要的校验码不同,最后产生的助记词长度不同,如下表:

BIP39 中目前支持多种语言的此表,每个词表的长度是 2^11=2048。· English· Japanese· Korean· Spanish· Chinese (Simplified)· Chinese (Traditional)· French· Italian可能有同学会问,表面看起来助记词就是随机排列的 12 词语,应该很容易暴力破解?下面的我们以 12 长度的助记词为例分析下暴力破解的难度:· 可能的助记词数量=2048!/(2048 – 12)!=5.27e+39· 每秒尝试 10000 次,每年能尝试的数量为 10000 * 60 * 60 * 24 * 364=3.15*e+11· 需要 1.67e+28 年才能穷举所有的助记词还不用说助记词的长度是可变的,每个助记词下面的的钱包数量也是近乎无限的。暴力破解的难度不用多说。有了助记词之后,怎么生成 HD 钱包呢,HD 钱包的关键是种子,只要从助记词恢复出种子即可,整个过程如下图:

JS 代码实现如下:

function mnemonicToSeed(mnemonic, password) { var mnemonicBuffer=Buffer.from(unorm.nfkd(mnemonic), ‘utf8’); var saltBuffer=Buffer.from(salt(unorm.nfkd(password)), ‘utf8’); return pbkdf2(mnemonicBuffer, saltBuffer, 2048, 64, ‘sha5

12’);}

可以看到,从助记词到种子的过程中,加了两个机制来增加暴力破解的难度:· password 机制,这样助记词即使泄露,密码不对也无法拿到正确的种子,算是双保险;· pbkdf2 机制,比较弱的密码经过这个环节随机性会大大增强,也正是这个运算会增加暴力破解的计算量;

到这里,BIP32、BIP44、BIP39 的核心内容我们都理清楚了,从助记词生成 HD 钱包的流程如下图:

{width=100%}以以太坊为例的助记词 HD 钱包生成过程简化如下(这里用到了 bip39、hdkey、ethereumjs-util 等库):

const bip39=require(‘bip39’);const HDKey=require(‘hdkey’);const EthUtil=require(‘ethereumjs-util’);const mnemonic=bip39.generateMnemonic(128);const seed=bip39.mnemonicToSeed(mnemonic, ”);const master=HDKey.fromMasterSeed(seed);const account=master.derive(“m/44’/60’/0′”);const addr=account.deriveChild(0).deriveChild(0);const pubKey=EthUtil.privateToPublic(addr.privateKey);const address=EthUtil.publicToAddress(pubKey).toString(‘hex’);

钱包有了之后,用它去签名交易、再把交易广播出去就不在本文的讨论范畴之内,感兴趣的同学可以自行研究。读到这里相信你对于 HD 钱包的几个核心提案、安全隐患以及助记词的基本原理已经有比较不错的理解。

 2/2   首页 上一页 1 2

本文采摘于网络,不代表本站立场,转载联系作者并注明出处:http://www.longfuchaju.com//chuangye/gushi/5454.html

联系我们

在线咨询:点击这里给我发消息

微信号:wx123456