博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
比特币从地址逆向计算私钥
阅读量:6431 次
发布时间:2019-06-23

本文共 4368 字,大约阅读时间需要 14 分钟。

hot3.png

区块链

区块链简介

说到比特币,就不得不提区块链。那什么是区块链呢?

区块链本质是一个数据集,只不过数据的组织采用了比较特殊的方式,就是把数据拆分为一块一块的小数据集。

为什么要进行数据拆分呢?因为区块链的作用是做为开放式的分布式的人人都可以修改的账本。这就需要防止恶意修改。

分成小的数据块之后,我们可以给每一个数据块加一个锁,要修改数据就得先找到钥匙,找钥匙的过程是一个需要大量计算过程,比特币使用的是工作量证明机制(PoW)。

区块链的链体现在什么地方呢?在于每一个小的数据库的钥匙都依赖于前一个块的钥匙,这样就形成了一个链式结构。这样做的目的是增加篡改数据的难度,降低篡改数据的可能性,因为篡改一个块的数据,就得修改这个块数据后的所有数据。

打包区块的计算

找钥匙的过程比较复杂,这里我们简化一下,首先看一下区块链的每一个块中包含的属性:

  1. Index:第几区块(创世区块的索引为0)。
  2. Hash:当前区块的Hash值。
  3. Previous Hash:上一个区块的Hash值。
  4. Timestamp:当前区块创建时的时间戳。
  5. Data:存储在当前区块上的交易信息。
  6. Nonce:参与hash运算的数值,使区块的hash值满足指定条件
function isValidHash(hash, difficulty) {  for (var i = 0, b = hash.length; i < b; i ++) {      if (hash[i] !== '0') {          break;      }  }  return i >= difficulty;}let nonce = 0;let hash;let input;let difficulty=4;while(!isValidHash(hash,difficulty)) {       nonce = nonce + 1;  input = index + previousHash + timestamp + data + nonce;  hash = SHA256(input)}

钥匙就是使得就算结果满足特定条件的nonce值,难度difficuty一般值的是前缀有多少个0,比如说difficulty等于4,就是要求调整nonce的值,一般算法是从0递增,使得通过sha256之类的hash算法的结果的前缀至少包含4个0。

根据hash算法不可逆的特性我们知道不可能通过一个值来逆向计算nonce,所以大家都只能老实的做搬砖式的迭代计算。

有很多同学可能会有疑问:既然大家都只能搬砖,那肯定是力气大的先搬完啊!也就是计算能力强的计算节点会先计算出结果。

主要2点:

  1. 算法可以不同,比如有的人喜欢nonce每次加1,也可以每次增加其他的值,比如2
  2. data不同,data一般是交易,一般会有一个交易池,每一个人选取不同的交易构成data数据

通过地址逆向计算比特币私钥

椭圆曲线算法

要逆向计算比特币私钥,首先得知道什么是比特币私钥,什么是比特币的公钥。说到公钥私钥那肯定得涉及到非对称加密算法,比如RSA,椭圆曲线算法等。

比特币选择的是椭圆曲线算法:

y^2=x^3+ax+b4a^3+27b^2!=0

比特币选用的是Secp256K1参数:

a=0b=7p=FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2FX: 79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798Y: 483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8

其中X\Y是生成点的横纵坐标。

椭圆曲线算法不是通过坐标解方程这么简单,而是利用椭圆曲线定义了一个群,椭圆曲线方程的作用是把几何运算转换为代数运算。

这里没有图不太好说,椭圆曲线算法这里就不详细的介绍了,可以自己搜索引擎搜索相关资料,后面介绍了一本书里面详细的介绍了椭圆曲线算法,有兴趣可以看一下。

当然页可以直接下载《以太坊智能合约开发实战》这本书的比特币章节的pdf文件,下载链接为:

提取码为:wb7k

这里简单的说一些就是使用CSPRNG生成一个随机数做为私钥,私钥做椭圆曲线乘法运算乘以生成点,转换为椭圆曲线方程的代数运算,计算得到一个椭圆曲线上的点为公钥。

私钥是一个随机的大整数,而公钥是一个点

私钥到地址

要想暴力逆向计算私钥,当然首先得了解私钥是怎么来的。

比特币的使用可以通过CSPRNG生成,当然也可以自定义,只要范围在1到n-1之间就可以了,其中n是椭圆曲线参数secp256k1中的n值。有了私钥privateKey,计算公钥就非常容易了,使用椭圆曲线乘法:

publicKey(px,py) = privateKey * G(x,y)

其中*表示椭圆曲线乘法,G是椭圆曲线参数secp256k1中指定的生成点G。

私钥生成

那么怎样计算地址呢?这个过程就要稍微复杂一点了,如上图所示,首先通过CSPRNG生成一个随机数作为私钥,然后通过私钥计算公钥,我们知道公钥是一个点,不好计算Hash值,所以需要做一点转换,怎样转换呢,首先拼接上一个04前缀,然后拼接公钥的横坐标,再拼接上公钥的纵坐标得到data。

然后计算data的sha256的值得到R,计算R的ripemd160得到一个extendR,extendR拼接上00前缀,然后对extendR进行2次sha256哈希计算取前4个字节,然后用extendR拼接上前面计算得到的4个字节得到data,最后对data做一次base58check编码就得到了最后的地址了。

公钥的压缩

压缩公钥是为了减少比特币交易的字节数,从而可以节省那些运行区块链数据库的节点磁盘空间。公钥是椭圆曲线上的一个点,把点转换为数字使用的方式是加上04前缀,拼接上点的横坐标x,然后再拼接上点的纵坐标y,所以公钥转换为数字有520位,其中十六进制前缀04占一个字节8位,x坐标256位,y坐标256位。 公钥是怎样压缩的呢?对于比特币来说,椭圆曲线的参数确定了,也就意味着了椭圆曲线,所以我们可以通过横坐标x就算得到纵坐标的值y。我们只需要存储点x的值就可以了,当需要纵坐标y的值的时候做一次计算就可以了。如图3.8所示,是公钥的格式获取流程图,非压缩格式加上04前缀主要是为了区分公钥有没有被压缩。

公钥压缩

判断纵坐标的奇偶性,是因为椭圆曲线的y值计算有开方运算,所以要区分y的正负值,如果y是正数则添加02前缀,如果y是负数则添加03前缀。奇偶性判断和正负判断有什么关联呢?我们知道椭圆曲线的运算都是被限定在有限域内的,在p阶有限域内,奇偶性和正负性相关。其中p是椭圆曲线参数中指定的,比特币使用secp256k1的p值为: FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE FFFFFC2F 2^256 − 2^32 − 2^9 − 2^8 − 2^7 − 2^6 − 2^4 − 1

私钥的格式

私钥有多种格式,最常见的就是十六进制格式,例如: 18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725 私钥还有两种格式,一种是WIF(Wallet import format),另一种是WIF-compressed。WIF格式和WIF-compressed格式差不多,我们先来看怎样通过私钥计算WIF,相比于从私钥到地址,私钥转换为WIF格式就平易近人的多了。

私钥格式

首先私钥添加一个十六进制前缀80,然后计算2次sha256作为一个中间值H,再在data的最后拼接上H的前4个字节作为校验码,得到data,然后对data计算base58check就获取到了地址的WIF格式了。WIF-compressed格式和WIF格式的计算流程基本一致,只是先为私钥添加01后缀在计算。例如要把私钥: 18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A206321725 转换为WIF-compressed格式,首先添加一个01后缀,变为: 18E14A7B6A307F426A94F8114701E7C8E774E7F9A47E2C2035DB29A20632172501 然后再执行和WIF同样的流程,获取到的就是WIF-compressed格式。因为基本和WIF流程一样,这里就不给流程图了。

逆向计算私钥示例

const bitcoin = require('bitcoinjs-lib')//找几个比特币较多的地址constrichAddrs=['16ftSEQ4ctQFDtVZiUBusQUjRrGhM3JYwe','16rCmCmbuWDhPjWTrpQGaU3EPdZF7MTdUk','183hmJGRuTEi2YDCWy5iozY8rZtFwVgahM']const N = 1000// 使用prototype方式给Array对象添加一个contains函数,用于检查是否包含指定元素Array.prototype.contains = function (obj) {    var index = this.length    while (index--) {        if (this[index] === obj) {            return true        }    }    return false}function conclusion(){    for(let i=0;i

书籍推荐

这里推荐一本书《以太坊智能合约开发实战》,对区块链、智能合约感兴趣的同学可以看一下,书中有很多原理性的知识还是值得一看的。

以太坊智能合约开发实战

书中介绍了很多东西比如P2P网络、椭圆曲线算法、智能合约等,了解P2P网络就能理解区块链的数据传递,了解椭圆曲线算法就能理解为什么计算私钥基本是不可能的。

当然也包括很多智能合约的知识,智能合约是比特币中没有的,以太坊基本是参考比特币实现的,但是最大的进步就体现在智能合约上,了解智能合约就会发现区块链真的会有很多有前景的使用场景,只需要等待技术更加成熟了就可以更好落地。

转载于:https://my.oschina.net/u/2474629/blog/3051444

你可能感兴趣的文章
flask 2 进阶
查看>>
sentences in movies and teleplays[1]
查看>>
【20181023T1】战争【反向并查集】
查看>>
win7网络共享原来如此简单,WiFi共享精灵开启半天都弱爆了!
查看>>
iOS9 未受信任的企业级开发者
查看>>
paper 40 :鲁棒性robust
查看>>
优化MySchool数据库(事务、视图、索引)
查看>>
使用笔记:TF辅助工具--tensorflow slim(TF-Slim)
查看>>
大话设计模式读书笔记3——单例模式
查看>>
实验三
查看>>
Vue 项目构建
查看>>
[Ruby on Rails系列]2、开发环境准备:Ruby on Rails开发环境配置
查看>>
android studio adb
查看>>
框架源码系列二:手写Spring-IOC和Spring-DI(IOC分析、IOC设计实现、DI分析、DI实现)...
查看>>
asp.net编译 懒人脚本
查看>>
二分答案经典入门题:)
查看>>
为什么你需要将代码迁移到ASP.NET Core 2.0?
查看>>
Servlet的多线程和线程安全
查看>>
存储树形的数据表转为Json
查看>>
CAN 总线通信控制芯片SJA1000 的读写
查看>>