主页 > 如何从imtoken转出以太坊 > 比特币钱包密钥管理概述

比特币钱包密钥管理概述

如何从imtoken转出以太坊 2023-01-17 10:37:34

钱包在整个区块链技术领域相对独立,与其他部分的交互很少;本文介绍了开发钱包密钥管理需要满足的功能和事实标准。

1.必备知识

这部分主要介绍开发钱包前需要了解的几个知识点。

(1).比特币私钥、公钥和地址的关系

比特币使用椭圆曲线密码学作为公钥和私钥的核心算法(所有使用的椭圆曲线都是Secp256k1)。私钥本质上是一个很大的随机数,保密存储,用于签署交易,从而证明UTXO的所有权,公钥是椭圆曲线上一点的坐标,曲线是计算出来的,这个计算是不可逆的,也就是没有计算方法可以从公钥计算出私钥。通常这里的私钥是32Byte,公钥是33Byte(压缩的公钥格式),比特币地址的本质是公钥的hash结果;这里使用的hash是sha256+ripemd160,也就是经常提到的为双哈希,或哈希160,地址通常表示为哈希结果的Base58Check编码。

(2).钱包概览

它不同于对生活的实际认知。比特币钱包不存储数字货币。钱包的基础是存储私钥,并使用私钥进行交易。签名用于证明可以花费一定数量的数字货币。

一个完整的交易(转账)过程包括创建交易、签署交易和广播交易。创建交易和广播交易不需要访问私钥,创建交易和签署交易不需要访问网络;所以钱包分为硬件钱包、冷钱包和热钱包。硬件钱包将私钥存储在独立的硬件上,存储的私钥无法被外部访问。签名交易的接口,安全性比较高,还需要独立购买硬件;冷钱包与硬件钱包相比,私钥存储在无法联网的机器上,交易是离线签名的;整个热钱包都已签名。进程全部在网络环境中,使用更方便;

钱包在另一个层次上分为全节点钱包和轻钱包,因为交易最终需要广播,而区块链是分布式去中心化的,所以钱包广播需要节点参与全节点钱包和轻钱包都是钱包本身作为一个节点,然后向其他节点广播交易。它是一个完全去中心化的结构。与轻节点的区别仅在于节点类型;还有一种钱包本身不是节点,而是多个钱包连接到一个中心化服务器。这个中心化服务器作为节点参与广播,钱包只包含交易的创建和签名交易。功能,签名后的交易通过其他协议(如HTTPS)传输到中心化服务器,中心化服务器将交易广播出去;中心化服务器还可以提供实时汇率等其他功能; Coinbase、Copay、Blockchain.info 其他钱包都有这样的CS结构;

还有一种交易所钱包,比如火币钱包,钱包本身不存储私钥,所有操作都与中心化服务器交互。至于中心化服务器是否会为每个用户创建一个私钥进行管理,还是个黑箱未知;

2.@ > 实施钱包密钥管理的多个标准

现阶段,对于钱包的发展,有几个事实上的标准需要遵循和执行,市面上现有的钱包都执行这样的标准

BIP-0032:分层确定性钱包(HD Wallet)规范; BIP-0039:私钥与助记码相互转换规范; BIP-0043:多用途高清钱包规范; BIP-0044:多账户多币种高清钱包规范;

这些规范基本由现有钱包实现,其中BIP-0032、BIP-0038、BIP-0039相互独立,处于不同的钱包实现过程中; BIP-0043是在BIP-0032的基础上制定的规范,BIP-0044在BIP-0043的基础上制定了更详细的规范;与BIP-0044同类型的规格有BIP-0045、BIP-0047、BIP-0049;

3. BIP-0032

比特币建议的相同地址被使用一次。与普通的私钥->公钥->地址关系相比,钱包需要维护多个地址,所以钱包可以做两个方向,一个是存储多个独立的私钥对应多个地址,这是一个非-确定性钱包;另一种思路是,一个种子(Seed)可以扩展生成多个私钥,每个私钥都有自己对应的公钥、地址,这就是确定性钱包; BIP-0032 定义了具有层的确定性钱包规范。

使用非确定性钱包有两个缺点。每个地址对应一个私钥,需要备份的私钥很多。丢失其中一个私钥也将丢失那部分比特币;使用过程中不断产生,需要时时备份。

HD钱包的种子本质上是一个随机数,或者说是其他规范生成的数字比特币钱包账号多少位,最常见的是通过BIP-0039的助记词生成;

首先种子通过HMAC-SHA512(Key="Bitcoin seed", Data=Seed)哈希函数生成一个64Byte的主密钥(Key是一个明确的字符串“比特币种子”),主密钥被分割分成两部分32Byte,左边作为主私钥,右边作为派生子密钥,称为链码。左侧的主私钥可以计算出公钥,从而计算出正常使用的地址;主密钥和链码,结合子密钥索引(索引为4Byte序列号),通过HMAC-SHA512推导出子密钥,主要分为三种:

(1).父级私钥-->子级私钥

这里使用HMAC-SHA512哈希函数,父的ChainCode作为哈希函数的key,父私钥计算出来的公钥(33Byte)作为哈希函数结合的Data索引。哈希函数还生成一个 64Byte 的子密钥,该子密钥也分为 32Byte 的两部分。右边的ChainCode用于子链衍生出自己的子链;左传数字添加父私钥得到子私钥;这里比特币钱包账号多少位,子私钥有一条椭圆曲线,并检查总和是否为零;验证通过则为合法子私钥,不合法则跳过当前索引。

(2).父公钥-->子公钥

这里HMAC-SHA512的计算和(1)一样,但是这里父公钥直接参与计算,而不是来自私钥;同样的hash函数分为两部分,右边的ChainCode,左边的32Byte通过椭圆曲线计算公钥,再与父公钥计算公钥,子公钥通过椭圆曲线的点坐标相加得到;

所以这里在使用中,在不安全的环境下,只能使用父公钥和链码来推导出需要的子公钥,整个过程不需要私钥的参与;这里需要明白一点,得到的子级公钥在使用中需要私钥解密,通过 (1) 中的同一个索引,计算得到的子级私钥和子级公钥这里计算的key是一个公私钥对;因为这里的椭圆曲线是一个可交换的群,满足交换律和结合律,而椭圆曲线中的私钥计算公钥是一个乘法(PubKey = PrevKey * P,P是特定椭圆曲线上的常数),所以这里满足ParentPrevKey * P + LeftB ytes * P = (ParentPrevKey + LeftBytes) * P,其中LeftBytes * P是左边椭圆曲线计算出来的公钥32字节;

(3).父私钥-->子公钥

父私钥有两种方式获取子公钥。一种方式是先通过(1),导出子私钥再计算子公钥;另一种方式是先计算父公钥,再通过(2)@)导出子公钥>;

增强派生

前面提到的父公钥和链码统称为扩展公钥,子公钥是在不安全的环境中衍生出来的,但是一旦子私钥泄露,扩展公钥中的链码可以推导出它所有的子私钥,另外子私钥和父链码存在推断父私钥的风险,所以引入了增强推导的概念。

增强派生只能从父私钥派生出子私钥得到子公钥,而不能进行上述公钥派生(2),具体派生过程和(The HMAC-SHA512 1) 中略有不同,与 (1) 中父私钥计算出来的公钥(33Byte)不同,增强推导通过0x00这样1Byte拼出私钥和索引为Data,其他推导步骤相同。增强推导不会将父链码暴露在不安全的环境中,因此比普通推导更安全。

子键的索引号和路径表示

索引的范围是2^32,其中前2^31表示正态推导,通常表示为索引号;后者 2^31 表示增强的推导。在序列号后添加撇号以表示增强的导数。比如0x80000000就是一阶增强导数的序号,通常表示为0',在钱包里有i'=2^31+i这样的关系。

Sub 键的路径由索引除以/表示;前缀分为m和M,m代表派生的子私钥,M代表派生的子公钥。例如,m/5/4'/0代表子私钥m/5/4'是第0个普通派生私钥,m/5/4'是第4个增强派生子私钥私钥m/5,m/5是第5个普通主私钥派生的子私钥。

4. BIP-0039

助记词比随机数表示更容易阅读和正确转录,让用户更容易复制钱包。助记词主要用于钱包备份和转账时使用。

助记词生成的基本过程是:

产生一个128bits的随机数,称为熵(以128bits为例);计算熵校验和:对熵进行SHA256哈希,取出前4位作为校验码; (校验码长度=总数据长度/32);132bits的长度与校验和拼接;132bits的长度按照11bits分为12个部分;每个11bits对应单词列表中的一个单词长度为 2048;

这12个词是熵对应的助记词,词表可以从词表中得到;

熵长不一样,对应的助记词个数也不一样;熵长度可以取以下值:

从助记词生成种子

这里使用了一种叫PBKDF2的算法来从助记词生成种子生成种子,PBKDF2函数接收两个参数:生成的助记词字符序列;第二个参数还有一个用于密码加密的盐。 salt(salt)的参数是字符串“mnemonic”和用户的可选密码拼成的String,没有可选密码的salt参数就是“mnemonic”。

PBKDF2使用HMAC-SHA512函数实现,循环2048次,最后返回一个长度为512位的种子;这里生成的种子可以作为上面BIP-0032的种子。

BIP-0043

因为BIP-0032层级可以无限扩展,每个层级可以有很多子密钥,定义过于松散,不同的钱包可能会定义自己的生成路径规则,所以BIP-0043定义了如何分层的规范使用钱包层次结构。

BIP-0043指定m/ purpose'/一级路径为目的,即定义路径遵循的规范,防止使用不同规范的路径冲突;例如,0'是BIP-32的默认钱包,44'是BIP-0044规范定义的前缀;本规范使用强化派生。

BIP-0044

BIP-0044在BIP-0043的基础上定义了更详细的路径规范:m/ purpose'/coin_type'/account'/change/address_index,这里目的还是遵循BIP-0043的规范。在 BIP-0044 中,它是一个固定值 44'; coin_type 定义了可以支持的数字货币的类型。已经注册的有比特币(0')、比特币测试网(1'),为多币种钱包的实现提供支持; account 定义了对多个账户的支持,从0开始, purpose、coin_type、account都是增强型衍生品; change 定义了外部地址(0) 和找零地址(1),外部地址一般用于接收转帐等)change address 字面意思是用来接收转帐的零钱;address_index 是地址序号从 0 开始的数字。

BIP -0045定义了另一种形式的路径规范,有兴趣的可以了解一下;

隔离见证

对于当前的钱包,BIP-0141 部分实施了隔离见证。简而言之,比特币扩张与 1M 的块大小限制相矛盾。有两种方法可以修改块大小(BCH 方案)和隔离见证。 Segregated Witness 是改变脚本签名(scriptSig)的结构,如果将区块取出单独存储,在计算区块大小时不会计算这部分,从而可以在一个区块中容纳更多的交易;这部分脚本签名仍在区块链中,并与交易一起验证。

支持隔离见证的钱包现在有共付额。

结论

除了上面介绍的公钥和私钥管理外,钱包一般需要创建交易并对创建的交易进行签名,将交易发送到区块链并由矿工确认。交易创建和签名是一个独立完整的内容,这里不再展开。

比特币钱包中的密钥管理相对来说是相对简单的,相对于整体结构来说也相对独立。钱包客户端也是用户与区块链之间的桥梁,所以实现钱包密钥管理的统一规范还是很重要的。