比特币钱包介绍(4)

强化子密钥派生

从扩展公钥派生出公钥分支的能力是非常有用的,但是它有个与生俱来的潜在威胁。访问一个扩展公钥不会给予访问子私钥的权限,但是,因为扩展公钥包含链码,如果子私钥已知或者不小心泄露,那么就可以利用子私钥和链码派生出所有子私钥。一个泄露的子私钥,配合一个父链码,就将导致所有子节点的私钥的泄露。更糟糕的是,一个子私钥,连同父链码,可以推导出父私钥。

为防止这种威胁,HD钱包使用了一个替代的派生函数,叫作强化派生(hardened derivation),它断开了父公钥与子链码间的关系。强化派生函数利用父私钥来派生子链码,而不是父公钥。这样就创建了一个父/子序列间的“防火墙”,链码无法用来推断父辈私钥或同级私钥。派生函数看起来与普通子私钥派生一模一样,除了使用父私钥替代了父公钥,如图4.13所示。

子密钥的强化派生,省略了父公钥

图4.13 子密钥的强化派生,省略了父公钥

当使用强化的私钥派生函数时,产生的子私钥和链码与普通的派生函数所产生的结果完全不同。其产生的密钥“分支”可以用于生成没有弱点的扩展公钥,因为它们包含的链码无法用于推导任何私钥。强化派生的引入,在扩展公钥所在层级与其上层级间形成了一个隔离。

简而言之,如果你想利用扩展公钥派生公钥分支的便利性,又不想使自己暴露在链码泄露的风险中,你需要从一个强化的父密钥来派生,而不是普通父密钥。作为最佳实践,为防止主密钥泄露,主密钥的第一层子密钥总是通过强化派生函数派生而来。

普通派生和强化派生的索引号

派生函数中用到的索引号是一个32位的整数。为了易于区分从普通派生函数和强化派生函数派生的密钥,索引号被拆分成两个范围。介于0到231-1(0x0到0x7FFFFFFF)之间只用于普通派生,索引号介于231到232-1(0x80000000到0xFFFFFFFF)之间则只用于强化派生。这样,如果索引号小于231,意味着这是个普通子密钥,而如果索引号大于等于231,子密钥就是强化的。

为了使索引号易于阅读和显示,强化子密钥的索引号从0开始显示,但是带一个单引号。第一个普通子密钥显示为0,但是第一个强化子密钥(索引号为0x80000000)显示为0′。相应地,第二个强化密钥的索引号为0x80000001,显示为1′,以此类推。当你看到一个HD钱包的索引号为i′时,它与231+i是等价的。

HD钱包密钥标识符(路径)

HD钱包中的密钥使用“路径”命名规则进行标识,树结构的层与层之间采用“/”分隔符进行分隔。从主私钥派生而来的私钥开始于“m”,从主公钥派生而来的公钥开始于“M”。这样,主私钥的第一个子私钥表示为“m/0”,主公钥的第一个子公钥表示为“M/0”。第一个子私钥的第二个孙私钥表示为“m/0/1”,以此类推。

一个密钥的“血缘关系”是从右往左读的,一直到主密钥的位置。举例来说,标识符“m/x/y/z”描述一个密钥,它是密钥“m/x/y”的第z个子密钥,而“m/x/y”是“m/x”的第y个子密钥,“m/x”是m的第x个子密钥。具体例子如表4.8所示。

表4.8 HD钱包的路径举例

blob.png

868区块链学习网为您整理《比特币钱包介绍(4)》仅供参考。