钱包的原理

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

相关文章

Spring Boot循环依赖原理、解决方案与最佳实践(全解析)

《SpringBoot循环依赖原理、解决方案与最佳实践(全解析)》循环依赖指两个或多个Bean相互直接或间接引用,形成闭环依赖关系,:本文主要介绍SpringBoot循环依赖原理、解决方案与最... 目录一、循环依赖的本质与危害1.1 什么是循环依赖?1.2 核心危害二、Spring的三级缓存机制2.1 三

C#中async await异步关键字用法和异步的底层原理全解析

《C#中asyncawait异步关键字用法和异步的底层原理全解析》:本文主要介绍C#中asyncawait异步关键字用法和异步的底层原理全解析,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录C#异步编程一、异步编程基础二、异步方法的工作原理三、代码示例四、编译后的底层实现五、总结C#异步编程

Go 语言中的select语句详解及工作原理

《Go语言中的select语句详解及工作原理》在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于switch语句,本文给大家介绍Go语言中的select语... 目录Go 语言中的 select 是做什么的基本功能语法工作原理示例示例 1:监听多个通道示例 2:带

鸿蒙中@State的原理使用详解(HarmonyOS 5)

《鸿蒙中@State的原理使用详解(HarmonyOS5)》@State是HarmonyOSArkTS框架中用于管理组件状态的核心装饰器,其核心作用是实现数据驱动UI的响应式编程模式,本文给大家介绍... 目录一、@State在鸿蒙中是做什么的?二、@Spythontate的基本原理1. 依赖关系的收集2.

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

Python中随机休眠技术原理与应用详解

《Python中随机休眠技术原理与应用详解》在编程中,让程序暂停执行特定时间是常见需求,当需要引入不确定性时,随机休眠就成为关键技巧,下面我们就来看看Python中随机休眠技术的具体实现与应用吧... 目录引言一、实现原理与基础方法1.1 核心函数解析1.2 基础实现模板1.3 整数版实现二、典型应用场景2

Java的IO模型、Netty原理解析

《Java的IO模型、Netty原理解析》Java的I/O是以流的方式进行数据输入输出的,Java的类库涉及很多领域的IO内容:标准的输入输出,文件的操作、网络上的数据传输流、字符串流、对象流等,这篇... 目录1.什么是IO2.同步与异步、阻塞与非阻塞3.三种IO模型BIO(blocking I/O)NI

JAVA封装多线程实现的方式及原理

《JAVA封装多线程实现的方式及原理》:本文主要介绍Java中封装多线程的原理和常见方式,通过封装可以简化多线程的使用,提高安全性,并增强代码的可维护性和可扩展性,需要的朋友可以参考下... 目录前言一、封装的目标二、常见的封装方式及原理总结前言在 Java 中,封装多线程的原理主要围绕着将多线程相关的操

kotlin中的模块化结构组件及工作原理

《kotlin中的模块化结构组件及工作原理》本文介绍了Kotlin中模块化结构组件,包括ViewModel、LiveData、Room和Navigation的工作原理和基础使用,本文通过实例代码给大家... 目录ViewModel 工作原理LiveData 工作原理Room 工作原理Navigation 工

Java的volatile和sychronized底层实现原理解析

《Java的volatile和sychronized底层实现原理解析》文章详细介绍了Java中的synchronized和volatile关键字的底层实现原理,包括字节码层面、JVM层面的实现细节,以... 目录1. 概览2. Synchronized2.1 字节码层面2.2 JVM层面2.2.1 ente