前言:哈希算法对于保证区块链网络安全很重要。为了减少哈希冲突可能性,要么提高哈希内部操作的复杂性,要么提高哈希输出的长度,寄希望于攻击者计算速度不够快。本文分析了哈希算法的历史,原理和未来,对于我们理解区块链的安全问题很有帮助。
新手在了解区块链的时候经常会接触到哈希(hash)和哈希算法(hashing algorithm)这样的概念,它们在安全方面可以说是无处不在。通过 P2P 运行像比特币,以太坊之类有众多节点的去中心化网络需要去信任机制和验证的高效性。
这就是说,这些系统需要想办法将信息以一种高效而简洁的方式编码,并允许其参与者能够安全而快速的进行验证。
比特币和以太坊所涉及的主要概念是「区块」,,这是一种包含交易记录,时间戳以及其他元数据的数据结构。这种数据结构安全性的关键在于:它能够将大量关于全球网络状态的信息压缩成一小段信息标准,并使这一小段信息能被高效的验证,这一小段信息被称为哈希。
即使仅仅改变输入信息的一个字符也会产生一个完全不同的哈希值!
加密学上的哈希被用于各行各业,从密码储存到文件验证系统。基本思想是使用一种确定性的算法,这种算法能够接受一个输入并每次都产生一个长度固定的字符串。也就是说,一个相同的输入得到的永远都是相同的输出。
除了这种确定性,哈希算法还有一个特性:输入中的任何一点点的改变都会导致输出变得完全不同。
哈希算法有一个问题,就是冲突必然性。它的意思是:由于哈希函数输出的字符串长度一定,不同的输入有可能会产生相同的哈希值。冲突是不好的,如果一个攻击者能够故意产生冲突,他便能够把恶意的文件或者数据伪装成正确的哈希值并将其传递下去。一个好的哈希函数的目标是让冲突的发生变得几乎不可能。
计算一个哈希值不应该太过高效,因为这会让冲突的实现变得太过容易。哈希算法应该能够抵御「原像攻击(pre-image attack)」。也就是说,根据已知的哈希值找到输入值应该是极其困难的(输入值被称作原像,比如 s = hash(x),根据 s 找到 x 应该是几乎不可能的)。
总结起来,一个好的哈希算法应该具备以下特征:
改变输入的任意一点都会产生一个完全不同的输出
发生冲突的可能性非常低
在不牺牲抵御冲突的情况下有一定的效率
最初的哈希算法标准之一是 MD5 哈希,它被广泛的应用于文件完整性验证(校验和),同时在网络应用的数据库中用于储存哈希密码。那时它的功能还十分简单,因为不论输入如何,输出是一个固定的 128 位的字符串,并且它使用并不有效的多轮单向操作(one-wayoperations across several rounds)来计算确定性输出。
由于输出字符串长度较短以及操作较为简单,MD5 很容易被破解并易受生日攻击(Birthday Attack)的侵扰。
什么是「生日攻击」?你可能听说过:如果一个房间里有 23 个人,那么两两生日重叠的可能性就有 50%,而在一个房间内如果提高到 70 人,那么这个概率就变成了 99.9%。这就是鸽子洞原则(pigeonhole principle),如果有 100 只鸽子只有 99 个洞,那么必然有一个洞中有两只鸽子。
放在哈希算法的案例中就变成了,一个固定长度的字符串意味着一个固定的排列组合数量,因此当输入值达到一定的数量时,冲突必然会发生。
太多鸽子了!至少有一只鸽子会与另一只共用一个洞
MD5 抵御冲突的能力如此之弱,以至于一个 2.4GHz 的奔腾处理器都能在数秒之内制造一次哈希冲突。事实上,由于 MD5 在较早年代的广泛应用,已经有大量的原像在线上泄漏,你甚至可以用简单的谷歌搜索来找到它们。
多样性和哈希算法的进化开端:SHA1 & SHA2
美国国家安全局(NSA)一直都是哈希算法标准方面的先驱,他们最早提出安全哈希算法,也就是 SHA1,这个算法输出的是 160 位固定长度的字符串。
然而,SHA1 仅仅在 MD5 的基础上提高了输出的长度,单向操作的数量以及单向操作的复杂性,但未做任何根本改进来使其能够抵御更强大的机器,这些机器尝试不同的攻击向量。
那么我们该如何提高呢?
SHA3郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。