由区块链引发的密码技术讨论(五)哈希

第五章 哈希

我们回顾第四章公钥的场景

假设小白作为黑客,他想破坏小强的约会,向餐厅客服发消息,取消晚上6点的定餐。小白也使用了餐厅客服的公钥加密信息发送给了餐厅客服,餐厅客服通过自己的私钥解密后,得到了两种不同的结果,那他就晕了,到底哪一个消息才是真的呢?现代密码技术为了解决这个问题,引入了消息认证,其底层的技术就是哈希函数,也叫做单向散列函数。

5.1 什么是哈希函数

哈希函数是密码学的一个重要分支,它是一种将任意长度的输入变换为固定长度的输出且不可逆的单向密码体制。哈希函数在数字签名和消息完整性检测等方面有着广泛的应用。

我们使用现在最常用的SHA256算法(也是比特币所使用的算法)为例:

import hashlib
text = '晚上6点,情侣套餐'
text = hashlib.sha256(text.encode('utf-8')).hexdigest()
print('"晚上6点,情侣套餐"哈希结果:',text)
text2 = '晚上7点,情侣套餐'
text2 = hashlib.sha256(text2.encode('utf-8')).hexdigest()
print('"晚上7点,情侣套餐"哈希结果:',text2)
text3 = '晚上6点,情侣套餐取消'
text3 = hashlib.sha256(text3.encode('utf-8')).hexdigest()
print('"晚上6点,情侣套餐取消"哈希结果:',text3)


-----------------------
运行结果:
"晚上6点,情侣套餐"哈希结果: 0c18560c685c9498ec2d74e2aa4354ead42fb375064d683914d2a09525c0ba58
"晚上7点,情侣套餐"哈希结果: d69f84442d5770483026e1204f88d3df5335e3489a16bdc6bddaa849becd8288
"晚上6点,情侣套餐取消"哈希结果: 3eff3e90740cdc6dfcb105881e48a2c8df1db564262001910cee111100c40b05

以上python3的代码中,我们可发现,不管文本的内容字数多少,采用SHA256哈希算法得到的结果都是都是十六进制的64位,也就是二进制的256位,我们把这么多位定义位散列值长度。

再仔细看以上代码,“晚上6点,情侣套餐”和“晚上7点,情侣套餐”虽然只是相差一个数字,但是散列值就有很大的不同,这个就是哈希的特性,使用这个特性,我们很容易的辨认文件、消息等内容是不是被修改过,只要被修改过哪怕1个比特位,所得到的散列值都是不相同的。

5.2 哈希函数最实用的应用场景

当我们给对方(比如你的同事,你的合作方)一个电子文件,你如何证明这个电子文件没有被对方修改过呢?哈希函数可以帮助你证明。

我们举个例子:

现在在D盘上有个文件,叫做“百年孤独.txt”,打开文件如下内容:

(这个文件可以是合同,至于为什么要举这个例子,主要是为了显示我很文艺。)

接着我们把文件复制到E盘,然后使用下面的python程序代码:

# -*- coding: utf-8 -*-

import hashlib

def get_file_sha1(tf):
    textfile = hashlib.sha256()
    while True:
        data = tf.read(1024)
        if not data:
            break
        textfile.update(data)
    return textfile.hexdigest()

with open('d:\\百年孤独.txt', 'rb') as file1, open('e:\\百年孤独.txt', 'rb') as file2:
    file1_sha1 = get_file_sha1(file1)
    file2_sha1 = get_file_sha1(file2)
    print('file1_sha1:',file1_sha1)
    print('file2_sha1:',file2_sha1)
    if file1_sha1 != file2_sha1:
        print('文件被改动过!!!!!')
    else:
        print('文件一致')

---------------
可以得到下面两个文件经过sha256算法的哈希结果
file1_sha1: fed45d5feb812c612b07e3bcedd4a3704422acaebcd223380dd6e0a35245dd99
file2_sha1: fed45d5feb812c612b07e3bcedd4a3704422acaebcd223380dd6e0a35245dd99
文件一致

现在我们把E盘这个文件修改一个很不起眼的地方,比如标点符号

这里我把原来的逗号改成了句号,我们再运行程序,看看比对的结果。

file1_sha1: fed45d5feb812c612b07e3bcedd4a3704422acaebcd223380dd6e0a35245dd99
file2_sha1: 05842406057bfc49916888f8bf391095469eb1a39b313c922fc0a3f1eab73b93
文件被改动过!!!!!

当文件有很多页的时候,这个就是最好的证明文件有无修改的办法,

在商业办公活动中,记录自己文件的哈希值并公布,是解决争端,保护自己的方式。

回头看这章前面的例子,小强在订餐的时候是可以随便发送自己订餐内容的哈希值给餐厅客服,从而构建了现代密码技术的完整架构。

5.3 哈希算法碰撞讨论

哈希函数具有输入敏感特性。也就是说,如果输入数据发生微小改变——比如改一个字符,那么输出将发生很大的变化。

这带来两点好处:第一,你无法通过输出的变化,来推测输入发生了什么变化。

第二,保存哈希值可以验证数据是否被篡改。

一般的,hash算法都是算力敏感型,意味着计算资源是瓶颈,主频越高的CPU进行 hash 的速度也越快。

也有一些hash算法不是算力敏感的,例如scrypt,需要大量的内存资源,节点不能通过简单的增加更多 CPU 来获得 hash 性能的提升。 

MD5是一个经典的hash算法,其和SHA-1算法都已被证明安全性不足应用于商业场景。为了提高安全性,NIST NSA 还设计出了 SHA-224、SHA-256、SHA-384,和 SHA-512算法(统称为SHA-2) ,跟SHA-1算法原理类似。比特币使用的是 SHA256。

一个优秀的hash算法,需要冲突避免,即很难找到两段内容不同的明文,使得它们的 hash 值一致(发生冲突)。即对于任意两个不同的数据块,其hash值相同的可能性极小;对于一个给定的数据块,找到和它hash值相同的数据块极为困难。

碰撞案例举例

1、"0e306561559aa787d00bc6f70bbdfe3404cf03659e704f8534c00ffb659c4c8740cc94

2feb2da115a3f4155cbb8607497386656d7d1f34a42059d78f5a8dd1ef"

2、"0e306561559aa787d00bc6f70bbdfe3404cf03659e744f8534c00ffb659c4c8740cc94

2feb2da115a3f415dcbb8607497386656d7d1f34a42059d78f5a8dd1ef"

上面这两段文字只有红色加大的数字不同,但是MD5 HASH后的值如下:

1、cee9a457e790cf20d4bdaa6d69f01e41

2、cee9a457e790cf20d4bdaa6d69f01e41

这个就是碰撞案例,像这种案例很多,现在的计算机只要数秒就能找到MD5的一个碰撞案例,因此,MD5在数年前就已经不被推荐作为应用中的散列算法方案,取代它的是SHA家族算法,也就是安全散列算法(Secure Hash Algorithm,缩写为SHA)。

安全散列算法与MD5算法本质上的算法是类似的,但安全性要领先很多——这种领先型更多的表现在碰撞攻击的时间开销更大,当然相对应的计算时间也会慢一点。

SHA家族算法的种类很多,有SHA0、SHA1、SHA256、SHA384等等。

其中SHA1是现在用途最广泛的一种算法,但是在2017年2月破灭了,谷歌宣布实现了 SHA-1 碰撞。

所以对于一些大的商业机构来说, MD5 和 SHA1 已经不够安全,推荐至少使用 SHA2-256 算法。

发布了29 篇原创文章 · 获赞 4 · 访问量 7568

猜你喜欢

转载自blog.csdn.net/cd4836/article/details/103777942