我的理解是 MD5 不安全的主要原因,就是计算速度太快,允许尝试太多次。人们建议改为使用设计为故意变慢的哈希,以提供更好的安全性。
但是,这仅以当前的计算速度提供安全性。一旦计算机变得更快,那么这些将不会比 md5 更好。所以我想知道,是否有可能拥有一个安全的散列函数,而不考虑执行所需的时间?
我的理解是 MD5 不安全的主要原因,就是计算速度太快,允许尝试太多次。人们建议改为使用设计为故意变慢的哈希,以提供更好的安全性。
但是,这仅以当前的计算速度提供安全性。一旦计算机变得更快,那么这些将不会比 md5 更好。所以我想知道,是否有可能拥有一个安全的散列函数,而不考虑执行所需的时间?
所以我想知道,是否有可能拥有一个安全的散列函数,而不考虑执行所需的时间?
不,当然不。可以将散列函数视为接受任何字符串并输出该字符串的短指纹的东西。如果我有一台足够快的计算机来列出所有可能的字符串并计算它们的指纹(也称为哈希值),那么我可以构建一个查找表,将每个哈希值映射回产生它的字符串。使用具有无限大内存的无限快计算机,我可以构建一个查找表,它可以破坏任何散列函数,甚至是理论上的散列函数。时期。
对于SHA2
具有 256 位输出的真正散列函数,假设您神奇地获得了所有 2 256 个可能输出的查找表,并假设执行每个散列需要 25 毫秒,则需要6.7x10 57 x 年龄宇宙只是为了验证查找表是正确的。现在,如果不是交给查找表,而是必须自己通过反复试验来计算,这个数字会更大。所以是的,所有哈希函数都可以被“非常快的计算机”破解,但就像真的非常非常快,就像宇宙时代一样,比我们今天拥有的任何计算机都快。[正如@BlueRaja-DannyPflughoeft 在评论中指出的那样,获得足够的电力来进行这种计算需要消耗几颗恒星,因此对于前星际社会来说,这在物理上是不可能的]
对现代哈希函数的攻击是易于处理的,这迫使我们使用诸如 salt&iterate 之类的技巧来降低它们的速度,原因是对于密码之类的东西,您不需要检查所有 2 256个可能的前映像。如果每个人都使用随机密码生成器,那么这将是真的,但人们不会……事实上,我们中有 1.5% 的人(每 68 人中有 1 人)使用密码“123456” (来源). 所以你只需要检查人们通常用作密码的东西。10 万个最常用密码的列表可以让您了解互联网上的几乎所有用户,如果只对它们进行一次哈希处理,一台普通的计算机可以在几分钟内检查这些密码。我们通过使每个哈希计算花费更长的时间来补偿人们的弱密码。如果它们被加盐和散列 10,000 次,那么在普通硬件上的几分钟在定制 GPU 装备上会长达几个月。
总之; 我们在哈希方面遇到的很多问题并不是因为哈希本身很弱,而是因为我们要求它们保护易于猜测的数据。
首先,MD5 除了散列速度快之外还有其他问题,包括碰撞漏洞。
一旦计算机变得更快,那么这些将不会比 md5 更好。所以我想知道,是否有可能拥有一个安全的散列函数,而不考虑执行所需的时间?
不,哈希函数本身总是可以使用足够快的计算机来破解(足够快是模棱两可的灵丹妙药)。然而,散列算法的实现可以解决这个问题。
例如,bcrypt提供了解决计算速度提高的机制。
bcrypt 使用轮的概念来计算哈希。例如,bcrypt 将使用盐和多轮对您的密码进行哈希处理:
bcrypt("password","salt",10000)
注意:正如darkhogg所指出的 ,rounds 参数实际上并未提交给 bcrypt。而是发送一个工作因素。不同之处在于发送的实际上是一个数字 N,它是用于计算轮数的指数。因此,尽管此处使用 10,000 作为轮数的示例,但您需要提供的实际工作单位才能获得 10,000 发子弹会小得多。
在存储散列、盐和轮数之前,对组合的盐和密码进行 10,000 次散列。所以假设在实施的初始时间 10,000 轮散列需要 0.02 秒。在初始实施一年后,您注意到 10,000 轮只需要 0.01 秒,或一半时间。您可以将轮数更改为 20,000。下次用户登录时,他们的哈希将计算 10,000 轮进行身份验证,但哈希将存储 20,000 轮,以供将来验证。
正如 Mike Ounsworth、amccormack 和 Romain Clair 在他们的回答中所说,如果您拥有无限的计算能力,那么您将能够通过简单地(预)计算每个可能的输入来破坏任何哈希算法。
您真正的问题可能是:我需要哈希做什么以及保存多久? 因此,如果您使用散列存储密码,我推荐此链接: 如何安全地散列密码?
但是,如果您只是需要它,因为您想为某些输入唯一地计算一个临时标识符,那么 md5 对您来说可能仍然足够。
一切的安全总是处于变化之中。40 年前,DES 算法也被广泛认为是安全的,但计算速度的提高使得它可以用相当数量的专用硬件破解。
30 年前,unix crypt 算法(也基于 DES)被认为在生成散列密码时足够慢以保证安全。它现在已经过时了。
更现代的密码散列算法(如 bcrypt)被设计为具有可变的难度来解释计算速度的提高。因此随着计算能力的增加,算法的难度可以增加以跟上。简单地增加我们在过去 40 年中看到的原始计算能力不太可能使 bcrypt 过时。
安全存在于上下文中,并且上下文总是在变化的。尽管如此,我们只能解释我们可以预测的变化。计算能力的提高是可以预见的变化。然而,我们不能计划未知的算法中断(就像 MD5 发生的那样)。
关键是任何安全都可能随时被破坏。永远无法保证安全。