哈希函数:具有确定性和不可逆的输出值

哈希函数:具有确定性和不可逆的输出值

哈希函数和电子表格的函数

哈希函数(亦称散列函数或散列算法)是理解区块链工作原理的一个非常重要的基础知识。

哈希函数有很多种类,例如 MD、SHA 等。不过,在这篇帖子中,我们将重点介绍哈希函数中的加密哈希函数。

首先,我们来看看什么是函数?大家都很熟悉什么是电子表格,因为我们经常使用电子表格里的简单函数,甚至编辑过电子表格的函数。

类似于 =sum(5,7) 的一个输入。sum() 就是电子表格中一个简单的输入函数。它接受一列的输入数值 – 5,7 ,并将它们相加求其和。

简单的说,这个函数的作用就是求数值的总和。哈希函数的原理与电子表格函数的原理相同,不过它的输出结果并非是简单的数值加之总和。

哈希函数输出所谓的“哈希值” 。如下图所示,一串由十六进制字符所组成的字串:

b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9

哈希函数的属性

哈希函数
哈希函数接受任意的数字化数据并输出固定长度的哈希值

哈希值就像一串随机生成的乱数或文本。哈希函数可以输入任意长度或类型的数字化数据,包括数字、文本、图像、视频和电子书等。通过哈希将其转换为一串看似随机但是固定长度输出的字符串。

哈希的转换会丢失一些信息,这就是为什么我们不能对哈希值逆向解密的原因。比如我们对一千兆字节的文件进行哈希处理,最后生成 64 个字符的哈希值。显然,这在此转换过程中丢失了很多信息。我们怎么可能将 64 个字符”逆向解密”成一千兆字节的文件?

此时,您可能会意识到使用哈希函数的优势。我们可以用一串很短的字符来验证千兆字节文件的完整性。所以这个哈希值,有时我们也可以称它为摘要(digest)。

话虽如此,那么哈希函数到底有多重要? 它有什么用途?

我们已经知道哈希函数会生成一个固定长度的字符串,因此加密哈希函数可以用作密码验证。

举例来说,当您登录一个网站时,在您输入密码之后,后台程序会进行密码的比对,以检验您输入的密码是否与您帐户中储存的密码一致。

如果我们的密码只是简单的直接储存在服务器中的某个文本文件中。那么当服务器被黑客入侵时,他们将会窃取整个系统中所有存有密码的文件并获得用户的密码。

事实上,大多数网站都在使用哈希函数并将您的加密哈希值储存在服务器的数据库中。例如我的密码“R@ck3ton3”,其 MD5 生成的哈希值为:

85B50CB4B8BCEED3BDA9EDFE9AAB8F39

网站将我的密码的哈希值储存在其数据库中,而不是我原始的密码。

加密哈希函数
后台程序会对登录密码进行哈希值比对

换个方式来说,后台程序使用与最初创建密码时相同的加密哈希函数进行哈希转换,然后再对两个密码的哈希值进行比对。

也许你会想,如果服务器被黑客入侵了,难道他们不能用哈希密码逆算哈希函数来还原我的密码吗?

实际上,答案是否定的!

不可逆的哈希值
哈希值是不可逆的

就好比我们之前提到的电子表格中求和函数的例子,如果只知道它的结果是 12,我们是无法知道其原始的组合是什么!可能是 7+5、还是2+10 或是 -23+35

更何况是,加密哈希函数的运算更加复杂。再加上哈希函数输出的特性,使其应用更为不可逆,更加的安全!

由于黑客无法获得密码文件,那么他们唯一的方法就是猜测您的密码。通常,他们会进行所谓的字典攻击,即对一些常见的单词、短语或是变体字串进行哈希运算,并尝试找到匹配的哈希值。

假设我的密码是 “stone”,那么黑客将会很快破解我的密码。这也就是当我们创建密码时,为什么网站都会要求密码输入必须混合大小写字母、数字和符号!

如果我将密码更改为 “St0n3” ,那么黑客们几乎不会对 “St0n3” 这样的字串进行哈希运算。这样子我的密码就不容易破解了,也会更为安全。

像我密码 “St0n3” 的哈希值为:

C8F80B41B936F939D85E6CBAEB6E3600

倘若黑客猜测我的密码为 “st0n3”,并对其进行哈希运算,结果是:

8DB4FE8ECADFD5D5664D8C2C245FC882

两者的哈希值完全不同!

非常明显的,即使是非常相似或近似的输入,其输出的哈希值也会完全不一样。因此,哈希函数不仅不可逆,还会因改变一个字母或符号,使得输出的哈希值亦会变成不一样。

数字指纹

两个不同的密码在经过哈希运算后得到相同的哈希值,这样的结果就是哈希碰撞。

加密哈希函数有不同类型, 其输出结果的长度也不一。例如常见的 SHA-128 哈希函数, 它的输出结果为 128 位元的二进制位. 而 SHA-256 的输出长度则为 256 位元的二进制位。

二进制就是数字 0 和 1。经过哈希运算生成 16 位数二进制的哈希值,在 65,537 个用户中,必然会发生哈希碰撞。但是,如果将哈希值的长度扩展到 32 位数,那么哈希碰撞的概率就会下降到 4,294,967,296 分之一。

所以说,哈希碰撞是微乎其微的,也几乎是不可能发生的!

哈希函数的运算速度非常快,同时也不耗费太多的计算资源。

基于上述哈希函数的属性,对于固定的输入,我们可以将其哈希值视为唯一的“指纹” 。

举个例子,您为客户准备了一份合同,然后通过电子邮件将其发送给客户以供审阅并重新发回给您。

您如何确认客户没有进行任何修改? 当然,您可以逐行仔细地阅读发回的合同以确保其与原始的合同一致,并无任何修改。

数字指纹
哈希值是其输入数据的唯一指纹

但这不是最好的方法!你可以对原始合同进行哈希运算,并将此哈希值与接收到的合同的哈希值进行比对。

因为哈希函数输出的哈希值就是其输入数据的唯一“指纹”。如果合同被修改过,那么其哈希值就不会匹配; 相反的,其哈希值肯定会匹配!

哈希函数的确定性

哈希函数可将任意长度的输入转换成或压缩为特定长度哈希值。对于像 SHA-256 这样的特定函数,相同的输入一定会产生相同的哈希值。此为哈希函数另一个重要的属性,即其输出具有确定性。

哈希函数的输出是一串很长的二进制数。例如 “1234” 的哈希值用二进制来表示,很容易眼花缭乱,使用也不方便:

0000001110101100011001110100001000010110111100111110000101011100011101100001111011100001101001011110001001010101111100000110011110010101001101100010001111001000101100111000100010110100010001011001111000010011111110010111100011010111110010000100011011110100

如果我们使用十六进制显示,虽然其中包含了字母,但阅读变得更加简单明了:

03AC674216F3E15C761EE1A5E255F067953623C8B388B4459E13F978D7C846F4

 

综合以上所述,哈希函数的属性:

  • 可以接受任意长度或类型的数字化输入
  • 具有确定性的结果,相同的输入总是给出相同的输出
  • 输出值是不可逆
  • 输出值可是微小、固定长度、独一无二的数字指纹
  • 即使对输入数据做微小的改动,输出值也会显著改变
  • 函数计算速度快,不耗费太多的计算资源

现在我们应该对哈希函数有足够的理解, 接下来我们将继续了解它是如何在区块中使用。

Comments

No comments yet. Why don’t you start the discussion?

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注