钱包的原理

2024-04-28 00:48
文章标签 原理 钱包

本文主要是介绍钱包的原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,我们需要知道一点,比特币钱包里面并没有比特币。钱包是管理密钥、地址、跟踪余额和创建交易的软件。我们的比特币数据是存储在区块链上的,而不是在钱包里。
经过前面几篇文章的解读,我们知道一个私钥生成公钥,公钥生成地址,这三者是一一对应的,就是一个私钥只有一个公钥和一个地址。但是我们在往交易所充币的时候,看到交易所为我们每个人生成一个独一无二的地址。这是怎么做的呢?接下来均益就来解读比特币的钱包。
目前钱包分为两种,一种是非确定性(随机)的钱包,就是随机生成多个私钥,钱包管理这些私钥。如果需要成千上万的地址,通过随机的方式来生成私钥,这就需要存储那么多无规律的私钥,这样就很麻烦不好管理。另一种是确定性(种子)的钱包,就是通过种子可以生成无数的私钥,我们只需要记住种子就可以了。我们在使用钱包时记住的助记词可以生成种子,只要我们保管好助记词,我们的币就能找回来。那么问题来了?

  1. 种子是怎么来的?
  2. 种子是怎么生成无数地址的?

带着这两个问题,我们来研究一下。先上一个大概图,然后我们再一步一步来解析


钱包生成私钥

主要流程是这样的

第一,随机生成128到258位的随机数,我们这里叫做熵;
第二,熵经过一定处理方法,生成助记词;
第三,助记词经过密钥延伸函数PBKDF2,生成种子;
第四,种子经过HMAC-SHA512算法,生成母密钥;
第五,通过CKD(child key derivation)函数,母密钥生成众多子密钥。

接下来均益一步步解析这里面的细节

一、从熵到助记词

1、随机生成一个128到258位的数字,叫做熵
2、熵通过SHA256哈希得一个值,取前面的几位(熵长/32),记为y
3、熵和y组成一个新的序列,
4、将新序列以11位为一部分,已经预先定义2048个单词的字典做对应,单词的列表像这样的 https://github.com/trezor/python-mnemonic/blob/master/mnemonic/wordlist/english.txt
5、生成的有顺序的单词组就是助记词
如图:

从熵到助记词

二、从助记词生成种子

助记词表示长度为128至256位的熵。 通过使用密钥延伸函数PBKDF2,熵被用于导出较长的(512位)种子。
PBKDF2的基本原理是通过一个伪随机函数(例如HMAC函数),把明文和一个盐值作为输入参数,然后重复进行运算,并最终产生密钥。如果重复的次数足够大,破解的成本就会变得很高。而盐值的添加也会增加“彩虹表”攻击的难度。
比特币钱包中,PBKDF2函数的第一个参数是助记词,第二个参数盐,由字符串常数“助记词”与可选的用户提供的密码字符串连接组成。使用HMAC-SHA512算法,使用2048次哈希来延伸助记符和盐参数,产生一个512位的值作为其最终输出。 这个512位的值就是种子。如图


从助记词生成种子

三、从种子到母密钥

512位分成平均分成两部分,左边的256位为母私钥,右边的256位为链码。母私钥、链码和索引号,CKD(child key derivation)函数去从母密钥衍生出子密钥。如图


从种子到主密钥

三、从母密钥到子密钥

母密钥、链码、索引合并在一起并且用HMAC-SHA512函数散列之后可以产生512位的散列。所得的散列可被拆分为两部分。散列右半部分的256位产出可以给子链当链码。左半部分256位散列以及索引码被加载在母私钥上来衍生子私钥。在图中,我们看到这个说明——索引集被设为0去生产母密钥的第0个子密钥(第一个通过索 引)。


从主密钥到子密钥

四、扩展密钥

母密钥和链码结合叫做扩展密钥,拥有扩展私钥可以推导出子私钥,扩展公钥可以推导出子公钥。拥有扩展公钥就可以推导出子公钥,在服务器不需要母私钥也可以,这样就更安全更方便。但是还有一个问题,那就是扩展公钥包含有链码,如果子私钥被知道或者被泄漏的话,链码就可以被用来衍生所有的其他子私钥。简单地泄露的私钥以及一个母链码,可以暴露所有的子密钥。更糟糕的是,子私钥与母链码可以用来推断母私钥。
为此,HD钱包使用一种叫做硬化衍生(hardened derivation)的替代衍生函数。这就“打破”了母公钥以及子链码之间的关系。这个硬化衍生函数使用了母私钥去推导子链码,而不是母公钥。这就在母/子顺序中创造了一道“防火墙”——有链码但并不能够用来推算子链码或者姊妹私钥。强化衍生函数看起来几乎与一般的衍生的子私钥相同,不同的是母私钥被用来输入散列函数中而不是母公钥。如图


扩展密钥

五、钱包索引

1、前面说到索引和私钥链码可以生成子密钥,这个索引号码是32位的整数。为了区分密钥是从正常衍生函数中衍生出来还是从强化衍生函数中产出,这个索引号被分为两个范围。索引号在0和2^31–1(0x0 to 0x7FFFFFFF)之间的是只被用在常规衍生。索引号在231和232– 1(0x80000000 to 0xFFFFFFFF)之间的只被用在强化衍生。因此,索引号小于231就意味着子密钥是常规的,而大于或者等于231的子密钥就是强化型的。

2、钱包索引识别路径
HD钱包中的密钥是用“路径”命名的,且每个级别之间用斜杠(/)字符来表示(见表5-6)。由主私钥衍生出的私钥起始以“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个子密钥。


钱包密钥识别符(路径)


作者:均益qrk
链接:https://www.jianshu.com/p/f4a41e62a682
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这篇关于钱包的原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/941940

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse

Redis中的AOF原理及分析

《Redis中的AOF原理及分析》Redis的AOF通过记录所有写操作命令实现持久化,支持always/everysec/no三种同步策略,重写机制优化文件体积,与RDB结合可平衡数据安全与恢复效率... 目录开篇:从日记本到AOF一、AOF的基本执行流程1. 命令执行与记录2. AOF重写机制二、AOF的

java程序远程debug原理与配置全过程

《java程序远程debug原理与配置全过程》文章介绍了Java远程调试的JPDA体系,包含JVMTI监控JVM、JDWP传输调试命令、JDI提供调试接口,通过-Xdebug、-Xrunjdwp参数配... 目录背景组成模块间联系IBM对三个模块的详细介绍编程使用总结背景日常工作中,每个程序员都会遇到bu

Python中isinstance()函数原理解释及详细用法示例

《Python中isinstance()函数原理解释及详细用法示例》isinstance()是Python内置的一个非常有用的函数,用于检查一个对象是否属于指定的类型或类型元组中的某一个类型,它是Py... 目录python中isinstance()函数原理解释及详细用法指南一、isinstance()函数

java 恺撒加密/解密实现原理(附带源码)

《java恺撒加密/解密实现原理(附带源码)》本文介绍Java实现恺撒加密与解密,通过固定位移量对字母进行循环替换,保留大小写及非字母字符,由于其实现简单、易于理解,恺撒加密常被用作学习加密算法的入... 目录Java 恺撒加密/解密实现1. 项目背景与介绍2. 相关知识2.1 恺撒加密算法原理2.2 Ja