稿件由路可比特整理自《区块链生存训练》
非对称加密
想理解非对称加密,就必须得了解“对称加密”,先来一个例子:我把饭团里的第二期内容汇总为一个PDF,并设置了一个密码:142857,这就是我们经常遇到的加密技术,所谓对称加密,就是加密和解密都是用一个密码(一套规则)。现在麻烦来了,我必须把这个密码告诉饭团会员们,否则大家无法打开PDF,但是天下没有不透风的墙,密码可能会被泄漏给更多的人,用这套密码加密过的文件都没有秘密可言了。
对称加密的缺点是,看似复杂,实则破解难度不高。
既然对称加密安全性不高,于是人们开始寻找一种更安全,更不容易被破解的加密技术---非对称加密。
非对称加密
(Asymmetric Cryptography)是加密的密码与解密的密码不是一样的,这有什么用呢?其它方面的例子不说了,主要就说比特币里面的例子。我们收款的比特币地址本质上是一个公开的密码,称为公钥(Public Key),别人给你付款时,拿这个公钥就可以生成交易记录,而这笔钱只有你的私钥(Private Key)才能打开。简单来说就是“在已知x的情况下,通过算法很容易求得y,但是知道了y,反过来求x却非常非常的困难”。
这里引入上一个概念:哈希算法。
哈希算法有一个显著的特点:单向加密,不可逆。即你无法通过结果值来逆向推导出最初值。是一种通过输入任意长度字符,生成固定长度字符输出的不可逆的算法。
公钥与私钥的关系就是:私钥经过单向的计算,生成公钥。
公钥就是由私钥经过类似哈希运算算法所得,即你无法通过公钥来逆向推导出私钥,但私钥拥有者却可以通过哈希运算来生成公钥。
在非对称加密算法中,主要有这两种典型的代表:
RSA算法
椭圆曲线算法
RSA算法的原理也很简单:
比如,任意生成一个200位的数字,将他分解成两个素数的乘机。我们知道,两个素数相乘是非常容易的,当是根据结果来推导出两个素数的值却极其困难,即使是超级计算机也要耗费海量的时间和资源才能算得。这便是数学中的一种难以可逆的计算方法。
椭圆曲线则算法是另外一种非对称加密的算法。
简单来讲,它是一个方程,在平面中呈现为曲线状,同样,它也是一个数学问题,单向计算很容易,逆向计算却极其困难,椭圆曲线算法太复杂,一时半会真心看不懂...
再说回比特币中的公钥和私钥的概念,对于普通老百姓经常被这些概念弄糊涂。再来梳理下:
基于椭圆加密的原理,由私钥是可以计算出公钥的,再由公钥经过一系列数字签名运算就会得到比特币钱包地址。
(1)私钥是一个随机数,32个字节随机生成。
(2)通过使用椭圆曲线加密算法,生成公钥,共65字节。
(3)公钥进行一系列的哈希运算,生成比特币地址。
简单支付验证
学SPV这个概念,必须知道轻钱包;想了解轻钱包,必须知道全节点钱包;当然在这些所有的学习之前,都得明白比特币里面的钱包究竟是什么意思,与我们手里拿的钱包有何不同。
我们知道区块链是一个公开的大账本,里面由区块链接而成,这些区块分散保存在世界各地的机器上,如果一个人的钱包软件中包含了所有区块的数据,那么这个钱包就是全节点钱包,比如著名的Bitcoin Core钱包软件,现在比特币的区块数据已经超过150GB,这样的钱包非常臃肿,只能在PC机上安装。
如果只保存部分区块数据,比如只保存与自己有关的区块数据,这样数据量比刚才说到的全节点钱包可能会小1000倍。以前常用的Multibit HD钱包就是轻钱包,可惜现在已经停止维护了。在 https://bitcoin.org/en/choose-your-wallet 网站上有多种钱包可供选择,Bither也是一种轻钱包。
SPV(Simplified Payment Verification)不保存完整的区块信息,只保存区块头信息,对于大多数用户来说,并不关心背后复杂的技术原理,我们只需知道它与其它钱包的区别、安全性风险就足够了。现在的很多轻钱包实现了这种技术,这类钱包虽然安全性不如全节点钱包,但假如你不是腰缠万贯,这种钱包的安全性也值得依赖。
关于SPV技术有一个类比,就是有两个人都从北京去罗马,一个人手里拿着全世界的所有地图册,大家都知道,一路上99%的地图都派不上用场,带着徒占地方;另一人手里可能只拿着中国地图、欧洲地图、罗马地图,他到达一个地点后,问问附近的居民,更新一下地图,再到一个地方,再更新一点数据,最终也能到达目的地。前者说的是全节点钱包,后者就是实现了SPV的钱包。
在bitcoin.org上挑选轻钱包软件时,你只需认准Simplified Verfication标志即可,你更需要注意它与Centralized Validation的区别,后者是指中心化验证,也就是说这款钱包软件是连接到一个中心服务器进行交易的验证,理论上是可以造假的。对于大额交易,还是亲自登录到blockchain.info等网站上输入交易ID,查查是否有6次以上确认最靠谱。
秒懂默克尔树
Merkle tree(默克尔树)是一种数据结构,通常是一个二叉树(也有可能是多叉树),它以特定的方式逐层向上计算,直到顶部。Merkle tree最为常见和最简单的形成是二叉默克尔树。
14-1默克尔树
在比特币的设计里,也使用了Merkle tree的数据结构,只不过里面存放的数据内容都是哈希值(HASH)。
14-2对每一层交易ID进行哈希运算
每个transaction ID进行哈希运算,生成一个哈希值H1, H2, H3等。然后相邻的两个哈希值相加之后,再进行哈希计算,形成它的父节点,以次类推,一直到根节点,形成默克尔树。
根节点的哈希值就是比特币单独一个区块的哈希值。比特币的每一个区块都可以通过其区块头的“前一个区块的哈希值”字段引用前一区块,形成一个区块链条。Merkle tree的根哈希值则可以确保区块中所有交易的真实性。
如果恰巧交易ID的总共数量为奇数个呢?那么排在最后的这个交易ID就copy自己一份,凑成偶数。
在比特币的设计里,有一点非常重要,一定要把所有的交易(transaction)按顺序排列下来,通过时间戳的功能就可以做到,如果顺序有误,那根哈希的结果就会大相径庭。
比特币的Merkle tree只存哈希值,没有任何实质的内容,实质的内容存在尾部的每笔交易里。
比特币为什么要用默克尔树
因为比特币有一个SPV功能,即:Simple Payment Verification(简单支付验证)。比特币的Merkle tree就是用来支持SPV功能。
SPV client 是个轻量级的客户端,SPV Client 只会下载所有的区块的头部信息,而不会下载交易部分,所以整个client下载比较快。
这里的头部信息仅包含5项内容,数据块大小为80字节:
上一区块头的哈希值
时间戳
挖矿难度值
工作量证明随机数(nonce)
包含该区块交易的梅克尔树的根哈希
SPV的目标是为了验证某个支付是否真实存在,并得到多少个确认。
支付验证的过程很简单,只是判断这笔支付交易是否得到了区块链节点共识验证,并得到了多少的确认数即可。
14-3默克尔树的验证过程
总的来说,Merkle tree 在区块链的应用实现了简单快速验证的功能。
领取专属 10元无门槛券
私享最新 技术干货