可能重复的问题:
为什么 MD5 哈希值不可逆?
我在阅读有关 MD5 的问题时,想起了一些令我感到困惑的事情。这是一个非常简单的问题,如果它不好,请原谅我。 我只是无法理解如何使用某些算法将某物转换为一件东西,并且没有使用相反的算法将其转换回来。
那么,这怎么可能呢?
此外,由于多个字符串可以创建相同的MD5哈希,因为它比输入字符串少数据,所以任何其他哈希系统会更好吗?
可能重复的问题:
为什么 MD5 哈希值不可逆?
我在阅读有关 MD5 的问题时,想起了一些令我感到困惑的事情。这是一个非常简单的问题,如果它不好,请原谅我。 我只是无法理解如何使用某些算法将某物转换为一件东西,并且没有使用相反的算法将其转换回来。
那么,这怎么可能呢?
此外,由于多个字符串可以创建相同的MD5哈希,因为它比输入字符串少数据,所以任何其他哈希系统会更好吗?
基本上,这是因为 MD5 的输出包含的信息比输入少。这基本上区分了哈希算法和加密算法。
这里有一个简单的例子:想象一个计算 10 位数字哈希值的算法。该算法是“返回最后 2 位数”。如果我取 8023798734 的哈希值,我得到的是 34,但如果你只有 34,你就无法知道原始数字是什么,因为哈希算法抛弃了 8 个数字的信息。MD5 也是类似的,只不过哈希是通过复杂的过程计算出来的,而不是简单地截取部分数据。
那么怎么样的哈希更好呢?首先,不同的哈希算法对于碰撞的抵抗能力可能更强或更弱(当两个输入产生相同的输出时)。碰撞的发生概率与哈希输出可能的数量成反比。哈希值的碰撞是一种不良特征,因为如果你的数据发生变化,你希望哈希值也会随之改变。因此,获得更好的哈希算法的方法之一是使用具有更多可能输出的哈希。在上面的数字示例中,取最后 4 位数而不是最后 2 位数,将具有相同哈希(技术上称为“预像”)的碰撞概率从 1/100 减少到 1/10000,因此更有可能所有你拥有的 10 位数字都具有不同的哈希值。
还有一个密码学安全的问题。当您想使用哈希函数来确保某些数据没有被篡改时,谁在篡改数据是无法预测会产生什么输出的输入是很理想的。如果他们可以预测,他们将能够以这样一种方式更改输入数据,使得输出(哈希)保持不变。再回到数字的例子,假设我要给您发电子邮件,其中包含数字1879483129,并且这个数字非常重要,必须无误地传递给您。我可能会打电话给您并告诉您这个数字的哈希值,该哈希值将为29,但由于“最后2位数字”的算法不是密码学安全的,恶意黑客可以在传输途中更改数字,比如改为5555555529,而您不会察觉到任何区别。
已经证明MD5算法不是密码学安全的(SHA-1算法也被破解)。这意味着可能会找到不同的输入对应于任何给定的输出。它仍然是用于保护随机位翻转等的良好算法,但如果有人有意损坏您的数据的可能性,您应该使用更安全的算法,例如SHA-256或更高版本,并且最好将其作为HMAC方案的一部分。
我就是不理解如何用某种算法将某物转换为一种东西,而没有任何办法使用算法逆转它。
你可以把一头牛变成汉堡,但你不能把汉堡变回一头牛。
这种转换通过破坏已有的数据来减少数据量,而且这些数据无法恢复。
这里有一个类比:
把你家里所有人的年龄加起来,只保留最后两位数字。
然后告诉我每个人的年龄是多少,仅基于那一个数字。
思考一下:
我有一个数字字符串,比如说它是“12345678”。
我有一个哈希算法,它只返回所有单个数字的总和,让我们称其为f()
所以, f("12345678") = 1 + 2+ .. + 8 = 36.
那么问题来了:
我们不能,因为f()是一种导致信息丢失的算法。
MD5是像f()这样的哈希算法,但更加复杂。
f(x_1x_2_x_3...)=1+2+3+...
是因为你从维基百科等渠道了解了MD5的工作原理。但这并不是一个解释! - Kalle Richter这里有一个简单的答案...
哈希值是有限的,而可哈希的明文值是无限的。
因此,反向计算给定的MD5哈希值会得出无数可能的明文值。
hash(x) = x<64 ? x : 63
。但就实际使用的哈希算法而言,我会非常惊讶地发现有一个将有限数量的输入映射到一个输出的算法。(对于主要算法,可能存在数学证明)。 - David Z嗯,不是要无礼,但我认为关于“输入比输出的信息少”的所有答案都把重点错过了。
MD5和类似的加密哈希码的主要用途是加密密码。在这种情况下,我并不关心能否重构原始字符串。我在意的只是能否构造任何一个散列值相同的字符串。
举个简单例子:假设我们的哈希算法是“取最后两位”。因此,如果我的密码是“12345678”,哈希码是“78”。有没有办法从“78”返回“12345678”?没有。但是,如果我正在黑客密码,我不在乎我知道你的原始密码是什么。我只需要一个密码让我进去。因此,如果我知道这是算法,我会说太好了,我会使用密码“99978”。它哈希到“78”,所以密码验证算法将通过,而我就进去了。
很明显,即使从“正确值哈希出任何值”的意义上来看,MD5也比“取最后两位”的简单算法更难以反转。但它是否真的不可能反转?这也让我感到困惑。所以当然,在这个过程中会丢弃信息。但是,我不能通过在丢弃信息的任何地方填入任意随机值来将其反转为“任何”值吗?我还没有看过实际的MD5算法。我假设它不是像将所有加号变成减号之类的易于反转的算法,否则早就被人做了。从有数百万黑客尝试破解这个密码算法的事实来看,即使它在理论上是可能的,也一定非常困难。
然而,一些哈希算法(如MD5)存在弱点,允许攻击者以比暴力破解尝试更少的努力来反转它(即找到具有给定哈希的消息)。在这方面,MD5被认为是完全破碎的。
然而,这并不意味着您不能恢复MD5的输入。它只是意味着您不能以100%的确定性恢复MD5的输入。为了使这更具体化,让我们再次看一下函数f(x)= x * x。现在,如果我告诉您对于f的任何给定输入,它为正数的概率为99%,那么在这种情况下,您可以非常好地猜测25的哈希值来自5而不是-5的值。这确实是人们能够破解哈希函数(包括MD5,事实证明它不是一个非常好的加密哈希函数)的方法。当涉及密码时,有些密码比其他密码使用得更频繁。您只需要获取这些密码的MD5并将其与某些哈希进行比较,如果它们匹配,则可以合理地猜测它来自该密码。
您可能也对阅读以下内容感兴趣:一对一函数, 单射函数, 密码哈希函数, MD5, SHA1, 以及来自Benlog安全博客的不要哈希机密信息。
更糟糕的系统将允许攻击者通过获得任何哈希来创建具有该哈希的文档。备受尊敬的CRC系统仍在许多硬件系统(例如以太网)中使用,容易受到此类攻击。与MD5一样,它是一种哈希函数,其输出无法从输入重构,但是给定任何输出,都可以轻松构造具有给定CRC-32或CRC-64签名的文档。更糟糕的是,您可以在这样的文档中放置任何文本,然后通过在末尾添加垃圾来获取所需的CRC。
CRC-32可以非常快速地计算,MD5需要更长时间,而SHA-1需要比MD5更长的时间。成本模型和信任模型都很困难。
一个真正好的哈希函数应该像CRC一样快速计算,并且像SHA-1一样难以构造两个文档的哈希值相同。不要抱太大希望...