什么是散列函数?

什么是散列函数(Hash)?

散列函数是一种能够把长度不定的输入转换为固定长度的输出的神奇函数。

我们生活中见得比较多的SHA-1和MD5就是散列函数。

 

以下是一些文本的SHA-1结果。可以看出,虽然这些文本的长度各不相同,但结果的长度都是一样的(不用数了,我很负责任地告诉你,它们都是40位的16进制数)。

输入不同长度的数据,SHA-1函数得到定长结果。
输入不同长度的数据,SHA-1函数得到定长结果。

这个函数有什么用呢?

  • 检验文件是否相同

我们下载一个文件的时候,有时会下载链接旁看到MD5或SHA-1数值。这是用来检验文件是否被正确下载,确保没有丢失数据或者被人暗中插入了其他内容。为什么散列函数能达到这个功能呢?因为,大多数的散列函数,对于输入的微小变化,会在输出上很明显地体现出来。

举例:还是刚才的双截棍,还是SHA-1算法:

输入数据发生微小的变化,SHA-1值都会截然不同。
输入数据发生微小的变化,SHA-1值都会截然不同。

可以看出,只是做了一点点微小的改动,SHA-1值就发生了明显的变化。而对比这个40位的数,当然要比对比数百字的歌词以及数亿个字节的文件要来得容易了。

 

  • 验证身份

为了寝室安全,某寝室制订了暗号计划:如果有人没带钥匙,敲门之后,里面的人喊“一二三四五”,外面的人对暗号“天王盖地虎”后,验证身份,里面的人就会开门。可是,有一天,隔壁推销员老王偷听到了这个暗号,也对着里面喊“天王盖地虎”,成功进入了寝室。

暗号泄露了怎么办?

有一天,小明了解了散列函数,恍然大悟,推出了改进型的暗号计划:敲门之后,里面的人随机给出一个代号,例如“你好”,外面的小强便把“你好天王盖地虎”输入到SHA-1函数里面,得到7228A…A2971,里面的小明把“你好天王盖地虎”输入到SHA-1函数里面,得到了一样的结果,便让小强进来了。

隔壁老王虽然偷听到了这个7228A…A2971,但当他来到寝室门口敲门的时候,里面的小明却给出了一个“Hello”!老王回答7228A…A2971之后,小明发现,“Hello天王盖地虎”的结果应该是07D88…E4981,于是按下按钮,开动机关将老王一脚踹飞。

然后,小黑来到门口敲门,小明报出代号“Bonjour”,小黑计算“Bonjour天王盖地虎”得到了35C40…DECE1,小明验证答案正确,便给小黑开了门。

为什么散列函数能这么用呢?因为散列函数并不是一个一一对应的函数,一个函数值可能对应着许许多多个不同的自变量。知道函数值,即使求出自变量所有可能的数值,也很难确定自变量的取值——更何况,通过散列值求出原数据一般只能通过穷举的方式进行。所以说,隔壁老王即使监听了所有的通信过程,也没办法推断出暗号是什么。

然而,我们说的“几乎无法进行”只是基于目前的技术水平而言的。Md5曾经也是一种广泛应用于身份验证场景的散列算法,然而,md5已经有严重缺陷被发现,现在,给出一段md5结果,无需太大的功夫即可得到一段md5数值相同的数据。

 

引申一种加密方式,叫做“公有密钥加密”,也称为“非对称加密”。公有密钥加密的意思是,加密用的钥匙是公开的。(当然,解密的密钥是私密的,不然要加密有何用?)上面的暗号系统即属于这种加密,我们一般访问https开头的网址也会用到这种加密。它的意义在于,如果通信过程从一开始就无法防止监听,(意味着没有办法安全地传递加密用的密钥,)那么用这种加密方法依然可以保证数据的安全。它的核心在于要找到一种正着计算很容易,倒着计算却很复杂的运算。如果我们有两个很大很大的质数,将它们乘起来,就得到了一个很大的,只有两个质因数的合数。可只知道这个合数,要分解出那两个质因数则难如登天。所以,我们只要利用这个合数来加密,用那两个质数来解密,就可以实现公有密钥加密了。它就叫做RSA。

留言

向我们提问或者评论我们的文章。您的留言不会被直接显示在网站内。
请在浏览器中启用JavaScript来完成此表单。
Email