乐趣区

关于比特币:比特币入门-②-钱包

比特币入门 ② – 钱包

钱包

概述

  • 定义

    • 狭义上讲,钱包是一个应用程序,为用户提供交互界面。钱包管制用户拜访权限,治理私钥和地址,跟踪余额以及创立和签名交易。
    • 广义上讲,从程序员的角度来看,“钱包”是指用于 存储和治理用户私钥 的数据结构,也是本章所指的钱包含意。
  • 钱包类型

    • 第一种类型是 非确定性钱包(nondeterministic wallet),其中每个私钥都是从随机数独立生成的,密钥彼此之间无关联。

      • 必须备份所有私钥。
      • 如果为了缩小备份而复用地址,这会将多个交易与此地址关联在一起,这样会减少隐衷泄露危险。
      • 除了简略的测试之外,不举荐非确定性钱包。
    • 第二种类型是 确定性钱包(deterministic wallet),其中所有的私钥都是从一个主私钥派生进去,这个主私钥即为种子(seed)。该类型钱包中所有私钥都互相关联,如果有原始种子,则能够再次生成全副私钥。

      • 1 型确定性钱包

      • 分层确定性钱包

        • 长处一:树状构造能够用来表白额定的组织含意。
        • 长处二:能够让用户去创立一系列公钥而无须通晓绝对应的私钥。(见子公钥的派生)

注记词

  • 助记词编码是示意确定性钱包的种子的英语单词序列。
  • 不同于“脑钱包”,脑钱包由 用户抉择 的单词组成,而助记词是由钱包 随机创立 并展示给用户的。
  • 创立注记词过程
  1. 创立一个 128~256 位的随机数(熵)。
  2. 提取随机数的 SHA256 散列值的前 x 位(x 等于随机数位数除以 32)作为校验码。
  3. 将校验码增加到随机序列的开端。
  4. 将序列按 11 位进行划分。
  5. 将每 11 位的值映射到一个含 2048($2^{11}$)个单词的预约义字典中。
  6. 生成的有程序的单词组就是助记词。
  • 从注记词生成种子

    • 助记词示意长度为 128~256 位的熵(随机数)。通过应用密钥延长函数 PBKDF2,熵被用于派生出更长的(512 位)种子。将所得的种子用于构建确定性钱包并派生密钥。
  1. PBKDF2 密钥延长函数的第一个参数是从步骤 6 生成的助记词。
  2. PBKDF2 密钥延长函数的第二个参数是盐。由固定的字符串“mnemonic”与可选的用户输出的明码字符串连贯组成。
  3. PBKDF2 将助记词和盐作为参数,调用 2048 次 HMAC-SHA512 散列算法,生成一个 512 位的值作为其延长的最终输入。这个 512 位的值就是种子。

创立主私钥和主链码

  • 根种子(还有可选明码)输出到 HMAC-SHA512 算法中就能够失去一个可用来发明主私钥(m)和主链码(c)的散列值。
  • 主私钥(m)能够生成绝对应的主公钥(M)。
  • 主链码(c)用于从父私钥发明子私钥的那个函数中引入随机数(熵)。

子密钥的派生

分层确定性钱包应用 CKD(child key derivation,子密钥派生)函数从父密钥派生出子密钥。

  • 子密钥派生函数是基于单向散列函数的,这个函数联合了:

    • 一个父私钥或者父公钥(ECDSA 未压缩密钥)
    • 一个 256bit 的链码,链码是用来给这个确定性过程引入随机数据的,以便晓得索引编号和子私钥也不足以派生其余子私钥。
    • 一个 32bit 的索引码,用于按程序生成相应的子私钥和子链编码。
  • 因为衍生方程是单向方程,所以子密钥不能被用来发现他们的母密钥。子密钥也不能用来发现他们的雷同层级的姊妹密钥。
  • 没有子链码的话,子密钥也不能用来衍生出任何孙密钥。你须要同时有子密钥以及对应的链码能力创立一个新的分支来衍生出孙密钥。
  • 父私钥 -> 子私钥 -> 子公钥
  • 父公钥 -> 子公钥

扩大密钥

将密钥以及链码这两个重要的局部组合在一起,称为扩大密钥(extended key)。术语“扩大密钥”也被认为是“可扩大的密钥”,因为这种密钥能够用来派生子密钥。扩大密钥能够简略地示意为将密钥与链码串联成的序列并贮存。

  • 两种类型的扩大密钥:

    • 私钥以及链码组成扩大私钥,前缀为 xprv,它可用来派生子私钥(子私钥能够用来派生子公钥)。
    • 公钥以及链码组成扩大公钥,前缀为 xpub,它能够用来派生子公钥
  • 扩大公钥及其利用:

    • 部署扩大公钥能够发明出有限数量的公钥以及比特币地址,然而不能破费发送到这个地址里的任何比特币。与此同时,在另一种更平安的服务器上,扩大私钥能够衍生出对应的私钥,签订交易领取破费。
    • 利用一:装置扩大公钥在电商的 web 服务器上。web 服务器能够应用公钥衍生函数去给每一笔交易(比方客户的购物车)发明一个新的比特币地址。服务器没有私钥,也就防止了被盗的危险。
    • 利用二:冷存储或者硬件钱包。在这种状况下,扩大私钥能够贮存在纸钱包或者硬件设施中,与此同时扩大公钥能够在线保留。用户能够任意创立“收款”地址,而私钥能够平安地在离线状态下保留。为了应用资金,用户能够用扩大私钥在比特币钱包中进行离线签名或者通过硬件钱包设施签名交易。
  • 存在的安全隐患

    如果晓得某个子私钥,有可能造成父私钥泄露,推导如下:

    1. 两种子密钥的派生形式的输出参数均为父公钥,父链码,父索引号,导致 512bits 输入统一,链码(右 256bits)也统一。
    2. 因为扩大公钥蕴含链码以及可生成后辈链码,可得左 256bits。
    3. 依据子私钥 = 左 256bits + 父私钥,如果相应子私钥泄露,则可逆推失去父私钥。
    4. 持续逆推最终可失去 已知最早的 扩大公钥所对应的私钥。

子私钥强派生

这个强派生函数应用了父私钥去推导子私钥。这导致 512bits 输入以及链码(右 256bits)与派生子公钥形式生成的不统一。因而无奈取得相应的左 256bits,也就无奈倒推出父私钥。

  • 留神:这样也会导致两种形式生成的子公钥也不雷同。如果后续应用扩大公钥的形式作为收款地址,后续派生子私钥的形式须要为失常派生,但就算后续产生私钥泄露,最多只会影响到这一分支。

因而强派生也因而被用于密钥树中 扩大公钥的上一层 以发明“间隙 / 防火墙”。

为了防止主密钥泄露,主密钥所衍生的第一层级的子密钥总是通过强化衍生得来。

索引码、密钥辨认符、门路

  • 索引码

    • 惯例派生索引码在 0 和 $2^{31}-1$(0x0 到 0x7FFFFFFF)之间。
    • 强派生索引码在 $2^{31}$ 和 $2^{32}-1$(0x80000000 到 0xFFFFFFFF)之间。
    • 为了让索引码更容易被浏览和显示,强派生的索引号码也是从 0 开始展现的,然而右上角有一个小撇号。第一个惯例子私钥因而被表述为 0,然而第一个强化子私钥(索引号为 0x80000000)就被示意为 0’。
  • HD 钱包密钥辨认符(门路)

    • 每个级别之间用斜杠(/)字符来示意。
    • 由主私钥派生出的私钥起始以“m”打头。由主公钥派生的公钥起始以“M”打头。
    HD path 密钥形容
    m/0 主私钥 (m) 衍生的第一个子私钥(0)
    m/0/0 第一个子私钥 (m/0)衍生的第一个子私钥(0)
    m/0’/0 第一个强化子私钥 (m/0′)衍生的第一个惯例子私钥(0)
    m/1/0 第二个子私钥 (m/1)衍生的第一个子私钥(0)
    M/23/17/0/0 第 24 个子公钥 (M/23) 衍生的第 18 个子公钥 (M/23/17) 的第一个子公钥 (M/23/17/0) 的第一个子公钥(0)
  • HD 钱包树状构造的导航

    BIP-44 指定了蕴含 5 个预约义树状层级的构造:

    m / purpose'/ coin_type' / account' / change / address_index

    • 第 1 层的 purpose 总是被设定为 44’。
    • 第 2 层的“coin_type”特指币种,容许多货币 HD 钱包中的货币在第二个层级下有本人的子树结构。
    • 第 3 层是“account”,这容许用户创立多个独立的子账号,便于财务统计或者部门治理。
    • 第 4 层是“change”。每一个 HD 钱包在这一层都有两个子树,一个用来创立收款地址,另外一个用来创立找零地址。留神无论先前的层级是否应用强派生,这一层级应用的 都是惯例派生。这是为了容许这一层级的树能够通过应用扩大公钥的形式生成下一级的公钥。
    • 被 HD 钱包派生的可用地址是第 4 层级的子级,就是第 5 层级的“address_index”。
    HD path Key described
    M/44’/0’/0’/0/2 比特币主账户的第三个收款公钥
    M/44’/0’/3’/1/14 比特币第四个账户的第十五个找零收款公钥
    m/44’/2’/0’/0/1 Litecoin 主账户中的第二个私钥,用于签名交易
退出移动版