开发HD钱包的关键:BIP32、BIP44和BIP39

开发HD钱包的关键:BIP32BIP44BIP39

电报联系方式

数字钱包概念

钱包是数字资产的安全存储和管理工具,每个数字资产都对应一个唯一的账户地址。只有持有对应账户地址的私钥,才能对数字资产进行交易签名和消费。私钥是数字资产的主要安全控制点,它是唯一的凭证,用于管理和支配您的资产。

开发HD钱包的关键:BIP32、BIP44和BIP39

私钥通过椭圆曲线生成公钥, 公钥通过哈希函数生成地址,这两个过程都是单向的。数字钱包实际是一个管理私钥(生成、存储、签名)的工具,注意钱包并不保存资产,资产是在链上的。

如何创建账号

账户的关键在于生成私钥,私钥是一个由32字节组成的数字,其本质是从1到2^256之间随机选择一个数字。因此,生成私钥的首要步骤也是最关键的步骤,需要寻找足够安全的熵源,即随机性来源。只要所选结果是不可预测或不可重复的,生成私钥的具体方法并不是最重要的因素。

举个例子,可以通过投掷硬币256次,用纸和笔记录正反面,并将其转换为0和1,从而随机生成256位的二进制数字,作为钱包的私钥。

从编程的角度来看,通常会从密码学安全的随机源中提取一串随机字节(不建议自行编写随机数生成器),然后使用SHA256哈希算法对其进行处理,以便轻松生成256位的数字。

BIP32

钱包也是一个私钥的容器,按照上面的方法,我们可以生成一堆私钥,而每个私钥都需要备份就比较麻烦。

为了解决这种麻烦,就有了BIP32 提议: 根据一个随机数种子通过分层确定性推导的方式得到n个私钥,这样保存的时候,只需要保存一个种子就可以,私钥可以推导出来,如图:

开发HD钱包的关键:BIP32、BIP44和BIP39

来分析下这个分层推导的过程,第一步推导主秘钥的过程:

开发HD钱包的关键:BIP32、BIP44和BIP39

通过将种子输入到HMAC-SHA512算法中,我们可以生成主私钥(m)和主链编码(master chain code)。这些生成的私钥或公钥以及主链编码与一个索引号一起作为HMAC-SHA512算法的输入,以继续派生下一层的私钥和链编码。这个过程会不断重复,每一层都以前一层的输出作为输入,从而生成更深层次的私钥和链编码。这种派生机制有助于构建层次结构的密钥,用于管理账户和子账户。

衍生推导的方案其实有两个:一个用父私钥推导(称为强化衍生方程),一个用父公钥推导。同时为了区分这两种不同的衍生,在索引号也进行了区分,索引号小于2^31用于常规衍生,而2^31到2^32-1之间用于强化衍生,为了方便表示索引号i’,表示2^31+i。

这个推导过程是确定也是单向的,子密钥不能推导出同层级的兄弟密钥,也不能推出父密钥。如果没有子链码也不能推导出孙密钥。现在我们已经对分层推导有了认识。

秘钥路径及BIP44

这种分层推导出的密钥通常用路径来表示,类似于树状结构,每个层级之间用斜杠 “/” 分隔。从主私钥开始,第一个子私钥路径表示为 “m/0″,而第一个公共密钥路径表示为 “M/0″。如果要派生第一个子私钥的子私钥,路径将是 “m/0/1″,以此类推,依次增加层级。这种路径表示方式有助于明确地指定每个派生密钥的位置和关系。

BIP44则是为这个路径约定了一个规范的含义(也扩展了对多币种的支持),BIP0044指定了包含5个预定义树状层级的结构:
m / purpose' / coin' / account' / change / address_index
m是固定的, Purpose也是固定的,值为44(或者 0x8000002C)

Coin type

这个代表的是币种,0代表比特币,1代表比特币测试链,60代表以太坊

Account

代表这个币的账户索引,从0开始

Change

常量0用于创建外部地址,通常用于接收付款,这些地址在钱包外部可见。常量1用于创建内部地址,也称为找零地址,这些地址用于处理交易变更,通常在钱包外部不可见。

address_index

这就是地址索引,从0开始,代表生成第几个地址,官方建议,每个account下的address_index不要超过20

根据EIP-85提议,以太坊钱包采用BIP-44标准,其中路径结构是 “m/44’/60’/a’/0/n”。在这个路径中,”a”代表账号,”n”代表生成的地址编号,而 “60” 是以太坊在SLIP-44提案中分配的编码。因此,为了开发以太坊钱包,需要了解比特币钱包提案中的BIP-32和BIP-39,因为它们提供了相关的关键概念和标准。

BIP39

BIP32提案让我们可以将一个随机数种子(通常以16进制表示)存储起来,而不必处理多个密钥,这在某种程度上更方便。然而,用户在使用中(例如,进行冷备份)可能会感到有些复杂。这时,BIP39就变得有用了。它使用助记词的方式来生成种子,用户只需要记住12个或24个单词的序列。这些单词序列通过PBKDF2与HMAC-SHA512函数结合,生成随机种子,成为BIP32的种子。这种方法使得管理和备份密钥更加用户友好。

可以简单的做一个对比,下面那一种备份起来更友好:

// 随机数种子
090ABCB3A6e1400e9345bC60c78a8BE7
// 助记词种子
candy maple cake sugar pudding cream honey rich smooth crumble sweet treat

生成助记词

助记词生成的过程是这样的:先生成一个128位随机数,再加上对随机数做的校验4位,得到132位的一个数,然后按每11位做切分,这样就有了12个二进制数,然后用每个数去查BIP39定义的单词表,这样就得到12个助记词,这个过程图示如下:

开发HD钱包的关键:BIP32、BIP44和BIP39

var bip39 = require(‘bip39’)
// 生成助记词
var mnemonic = bip39.generateMnemonic()
console.log(mnemonic)

助记词推导出种子

这个过程使用了密钥拉伸函数,其主要目的是增强弱密钥的安全性。PBKDF2是密钥拉伸算法中的一种常见选择。

PBKDF2的基本原理是通过重复计算,使用一个伪随机函数(通常是HMAC函数),将助记词明文和盐值作为输入参数,最终生成一个更长(通常为512位)的密钥种子。这个种子随后被用于构建确定性钱包,并从中派生出相应的密钥。

密钥拉伸函数需要两个关键参数:助记词和盐。盐的作用在于增加了暴力破解的难度,因为即使使用相同的助记词,不同的盐会导致生成不同的种子。盐通常由一个固定的字符串(例如”mnemonic”)以及一个可选的密码组成。需要注意的是,更改密码会导致在相同助记词的情况下生成不同的种子,增加了安全性。

开发HD钱包的关键:BIP32、BIP44和BIP39

var hdkey = require(‘ethereumjs-wallet/hdkey’)
var util = require(‘ethereumjs-util’)

var seed = bip39.mnemonicToSeed(mnemonic, “pwd”);
var hdWallet = hdkey.fromMasterSeed(seed);

var key1 = hdWallet.derivePath(“m/44’/60’/0’/0/0”);
console.log(“私钥:”+util.bufferToHex(key1._hdkey._privateKey));

var address1 = util.pubToAddress(key1._hdkey._publicKey, true);
console.log(“地址:”+util.bufferToHex(address1));
console.log(“校验和地址:”+ util.toChecksumAddress(address1.toString(‘hex’)));

密码可作为一种额外的安全因素来保护种子。即使助记词备份被盗,密码的存在可以确保钱包的安全性,前提是密码足够复杂且长度足够长。然而,这也意味着如果我们遗忘了密码,将无法恢复我们的数字资产。密码的存在提供了额外的安全性,但同时也带来了一定的风险,因为失去了密码将导致无法访取资产。

结论

HD钱包(分层确定性钱包)是为了简化私钥管理问题而提出的解决方案,它在BIP32标准中得到了定义。BIP44进一步规范了路径定义,为BIP32的分层提供了增强支持,并且还增加了多币种的兼容性。而BIP39则引入了助记词的概念,使种子备份更加用户友好。

目前,市面上的以太币和比特币钱包通常都遵循这些标准,以提供更便捷和统一的加密货币钱包体验。这些标准有助于用户更容易地管理和备份他们的私钥和资产。

开发联系:DEXDAO

 

 

© 版权声明

相关文章

暂无评论

暂无评论...