深入浅出区块链(5)区块链中的加密学
在区块链中使用了很多加密学算法,包括哈希算法、默克树、数字签名等。在这一节将逐个学习这些知识。
哈希算法
hash.png哈希算法是一种常见的单向加密算法,它将一串数据加密生成一串二进制,但不能由二进制还原为原来的数据。该算法有一下特点:
- 相同的输入得到相同的二进制串
- 不同对输入得到不同的二进制串,即有强对抗性,不同的数据不会产生相同的哈希值
- 输出的二进制长度是一致的
import hashlib
data1 = "Test1"
msg = hashlib.sha256()
msg.update(data1.encode("utf-8"))
output1 = msg.hexdigest()
print(output1)
hash1.png
# 再次计算
msg = hashlib.sha256()
msg.update(data1.encode("utf-8"))
output2 = msg.hexdigest()
print(output1 == output2)
True
# 使用不同的数据
data2 = "Test2"
msg = hashlib.sha256()
msg.update(data2.encode("utf-8"))
output3 = msg.hexdigest()
print(output3)
print(output3 == output1)
32e6e1e134f9cc8f14b05925667c118d19244aebce442d6fecd2ac38cdc97649
False
print(len(output1))
print(len(output3))
64
64
长度都为64,即256长度的比特位
hash2.png在区块链中很多地方用了哈希算法,比如对区块计算哈希值。在“区块链基础”部分中实现了一个简化版的区块链。在实际区块链中区块包含元数据的区块头和紧跟其后的构成区块主体的一长串交易,结构如下:
大小 | 字段 | 描述 |
---|---|---|
4字节 | 区块大小 | 用字节表示的该字段之后的区块大小 |
80字节 | 区块头 | 组成区块头的几个字段 |
1-9(可变整数) | 交易计数器 | 交易的数量 |
可变的 | 交易 | 记录在区块里的交易信息 |
其中哈希值和nonce等都放在区块头中,其结构如下:
大小 | 字段 | 描述 |
---|---|---|
4字节 | 版本 | 版本号,用于跟踪软件/协议的更新 |
32字节 | 父区块哈希值 | 引用区块链中父区块的哈希值 |
32字节 | Merkle根 | 该区块中交易的merkle树根的哈希值 |
4字节 | 时间戳 | 该区块产生的近似时间(精确到秒的Unix时间戳) |
4字节 | 难度目标 | 该区块工作量证明算法的难度目标 |
4字节 | Nonce | 用于工作量证明算法的计数器 |
这里涉及到另一个概念——默克(Merkle)树
默克树
Merkle.png默克尔树,又叫哈希树,是一种树的数据结构,由一个根节点、一组中间节点和一组叶节点组成。最下面的叶节点包含存储数据或其哈希值,其上的节点是它的子节点内容的哈希值。一个默克树的生成过程如下:
1.由数据生成一系列哈希值
Merkle1.png2.从上述哈希值再生成哈希值
Merkle2.png3.然后再生成根节点
Merkle3.png默克树有如下特点:
- 一般是二叉树,也可以多叉树,具有树结构的所有特点;
- 树的根节点只取决于数据,和其中的更新顺序无关。换个顺序进行更新,甚至重新从头计算树,并不会改变根节点;
- 当两个默克尔树根节点相同时,则意味着所代表的数据必然相同,用根节点校验可以大大减少数据的传输量以及计算的复杂度;
- 默克树的一个分支也是默克树,可以作为独立进行校验;
当区块链中的交易数据过多时,可以通过只保留默克树的根节点,删除其下的节点有效的节约存储空间。
数字签名
在区块链中还有一个重要的技术,那就是数字签名。类似在手写签名来确认直至内容,数字签名用于证实某数字内容的完整性和来源,保证签名的有效性和不可抵赖性。
数字签名使用了公钥密码学。公钥密码学是非对称加密技术,其相对于对称加密技术。在对称加密技术中加密使用相同的密钥加解密数据,为了让对方能够解密,需要同时将密文和密钥发给对方。
如果有人在传输过程中截取了密文和密钥,就一样能解密出明文,这就导致了安全性问题。
sign1.png在非对称加密中有公钥和私钥两个,公钥用来加密,私钥用来解密,公钥可以发给任意的人。
sign2.png在这个过程中只有私钥才可以解密,而加密用的是公钥,故不需要传输私钥,只要保证私钥放在安全的地方,被盗取后其他人还是无法破解密文。
sign3.png而数字签名就是基于上述非对称加密技术,不同点在于数字签名使用私钥生成一个签名,接收方使用公钥进行校验。比如上面用私钥解密得到明文后,用私钥进行签名进行回复,收到回复后用公钥解密得到的内容与数据相同即可证明签名正确。
sign4.png因为公钥和私钥是成对的,唯一对应的,私钥只有对方拥有,所以对方也不能对签名进行抵赖。
在区块链技术中常见的签名算法是椭圆签名算法。其算法用对椭圆曲线上的点进行加法或乘法运算来表达。区块链中私钥是一个随机数,通过椭圆曲线签名算法生成公钥。但反向从公钥计算出私钥几乎是不可能的。椭圆曲线签名算法还具有安全性高和存储空间占用小的特点。