如何才能无法“解密”MD5哈希值?

43

可能重复的问题:
为什么 MD5 哈希值不可逆?

我在阅读有关 MD5 的问题时,想起了一些令我感到困惑的事情。这是一个非常简单的问题,如果它不好,请原谅我。 我只是无法理解如何使用某些算法将某物转换为一件东西,并且没有使用相反的算法将其转换回来。

那么,这怎么可能呢?

此外,由于多个字符串可以创建相同的MD5哈希,因为它比输入字符串少数据,所以任何其他哈希系统会更好吗?


4
并非所有算法都是可逆的,这就是哈希运作的原因。 - slugster
MD5是不可逆的,但谷歌已经被用来搜索其存储的大量MD5数据库 - Pascal Thivent
这篇文章可以帮助你“反向解密MD5哈希”。http://stackoverflow.com/questions/1471654/reversing-an-md5-hash/ - berkay
13个回答

106

基本上,这是因为 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方案的一部分


85

我就是不理解如何用某种算法将某物转换为一种东西,而没有任何办法使用算法逆转它。

你可以把一头牛变成汉堡,但你不能把汉堡变回一头牛。

这种转换通过破坏已有的数据来减少数据量,而且这些数据无法恢复。


14
我认为这是我见过的最有启发性比喻,点赞!嗯...哈希函数和汉堡包。 - ig0774
6
当然,你可以把汉堡变成牛,就像你可以把炒鸡蛋变成鸡一样。你将汉堡喂给小牛,使其长成一头完整的牛。这种方法效率低下,会浪费大量美味的汉堡,但它是可行的。 - Remus Rusanu
2
@Remus,那你运行的时候有相当大的概率感染疯牛病。@Rob,把土豆做成薯饼会不会更好一点?我也喜欢牛,它们很好吃。+1 支持 @tangurena 的开头比喻! - Nathan Ernst
这并不冒犯,我只是真的很喜欢奶牛 =[ 我也不是素食主义者或其他什么的,你说得对,它们确实很好吃。但还是 =[ - Rob
18
就像汉堡一样,肉饼常需要加盐一样,哈希通常也需要加盐。 - Randolpho
你肯定可以利用汉堡中可用的DNA来重新创造你的奶牛,但问题是,一旦它开始生长,环境条件(如喂养和饲养方式等)可能会导致它与你原来的奶牛有物理上的差异 - 但它在基因上是完全相同的。 - Michael

17

这里有一个类比:

把你家里所有人的年龄加起来,只保留最后两位数字。

然后告诉我每个人的年龄是多少,仅基于那一个数字。


有人会说这是年龄问题。 - Mateus Viccari

4

思考一下:

我有一个数字字符串,比如说它是“12345678”。

我有一个哈希算法,它只返回所有单个数字的总和,让我们称其为f()

所以, f("12345678") = 1 + 2+ .. + 8 = 36.

那么问题来了:

已知f(x) = 36,是否可以得到原始值x?

我们不能,因为f()是一种导致信息丢失的算法。

MD5是像f()这样的哈希算法,但更加复杂。


你知道 f(x_1x_2_x_3...)=1+2+3+... 是因为你从维基百科等渠道了解了MD5的工作原理。但这并不是一个解释! - Kalle Richter
@KarlRichter 您是正确的,我应该提到这一点:“MD5是像f()一样的哈希算法,但更加复杂。” - Colin Niu

2

这里有一个简单的答案...

哈希值是有限的,而可哈希的明文值是无限的。

因此,反向计算给定的MD5哈希值会得出无数可能的明文值。


从技术上讲,对于某些哈希值来说,可能只有有限数量的不同明文与之对应,是这样吗? - Sebastian Paaske Tørholm
编辑了我的原始帖子,请阅读底部的新部分。 - Rob
2
@Sebastian P:并不完全正确。在(理论上的)无限输入集合中,MD5应该生成(理论上的)无限输出集合。(如果一个哈希函数不是1:1的,并且有无限数量的输入,那么给定任何一个哈希值是与有限数量的哈希值对齐是理论上不可能的;这是无限集合的一个推论,而不是MD5的一个推论,也就是说,有一定数量的有效MD5值,即2^128;对于每个哈希函数给定一个无限的值集合,都会有无数个碰撞)。 - ig0774
1
@ig0774:我猜从技术上讲,构建一个奇怪的哈希算法,将仅有限的一组输入映射到一个输出可能是可能的。在一个极端案例中,对于非负整数x的6位哈希函数, hash(x) = x<64 ? x : 63。但就实际使用的哈希算法而言,我会非常惊讶地发现有一个将有限数量的输入映射到一个输出的算法。(对于主要算法,可能存在数学证明)。 - David Z
@David:我想你对哈希算法的看法是正确的(这样的算法可能会满足某些技术需求)。我的观点是关于MD5算法的。 - ig0774
@ig0774:MD5哈希的数量是固定的,是的,可以使用该算法对无限数量的文本进行哈希,是的。我只是好奇为什么你说这2^128个哈希中每个哈希都保证有无限数量的明文与其哈希值相同;这个事实对我来说并不明显。很明显,这将是一个理想的属性,很可能在MD5中得到满足,但我很好奇这个声明的证明在哪里。 - Sebastian Paaske Tørholm

2
回答你问题的第二部分(第一部分已经被其他人充分回答):MD5被认为是不安全的,因为存在攻击密码的证明(即,在明文中可以进行更改,而不会导致MD5校验和的更改)。其他哈希技术可能不太容易受到任意哈希冲突的影响(至少还没有显示出SHA-2哈希集等存在任意冲突的可能性),因此,攻击者较难复制使用非MD5技术哈希的哈希值(当然,理论上,哈希碰撞攻击对于任何哈希函数都是可能的;如果不是这种情况,它就不能作为哈希函数成功。问题在于攻击者能否轻松地成功“伪造”一个“正确”的明文,即一个哈希值相同的明文)。
顺便说一下,明文的MD5校验和不一定安全,因为它包含“较少”的数据或者是“有损的”,而是因为从任意明文中,它计算出一个在固定范围内的校验和值(对于小于128位的明文,事实上,MD5校验和包含比明文更多的信息...),因此,理论上无限数量的明文都可以对齐到相同的MD5哈希值。

2

嗯,不是要无礼,但我认为关于“输入比输出的信息少”的所有答案都把重点错过了。

MD5和类似的加密哈希码的主要用途是加密密码。在这种情况下,我并不关心能否重构原始字符串。我在意的只是能否构造任何一个散列值相同的字符串。

举个简单例子:假设我们的哈希算法是“取最后两位”。因此,如果我的密码是“12345678”,哈希码是“78”。有没有办法从“78”返回“12345678”?没有。但是,如果我正在黑客密码,我不在乎我知道你的原始密码是什么。我只需要一个密码让我进去。因此,如果我知道这是算法,我会说太好了,我会使用密码“99978”。它哈希到“78”,所以密码验证算法将通过,而我就进去了。

很明显,即使从“正确值哈希出任何值”的意义上来看,MD5也比“取最后两位”的简单算法更难以反转。但它是否真的不可能反转?这也让我感到困惑。所以当然,在这个过程中会丢弃信息。但是,我不能通过在丢弃信息的任何地方填入任意随机值来将其反转为“任何”值吗?我还没有看过实际的MD5算法。我假设它不是像将所有加号变成减号之类的易于反转的算法,否则早就被人做了。从有数百万黑客尝试破解这个密码算法的事实来看,即使它在理论上是可能的,也一定非常困难。


最初的问题是关于是否存在算法,无法从输出中恢复原始输入。MD5 绝对符合这一要求。至于你提出的仅仅找到任何一个能够哈希为给定输出的输入的想法,如果您想建立一个查找表,那肯定是可行的,但这需要大量的计算能力。我认为您不可能只是反向运行算法,必要时填充随机数据,因为 MD5 在每个阶段都会混淆位。(我曾经知道这个算法,但我已经忘记了) - David Z
1
我同意这些答案在技术上是正确的,但我只是想指出它们与保护密码的真正问题并不相关。将其推向荒谬的极端,一个将所有输入数据丢弃并将一切映射到字符串“foobar”的算法将使得无法有任何线索知道原始输入是什么,但它作为一个加密密码的算法将是相当无用的! - Jay
无论如何,就像我所说的,我还没有研究过MD5算法。无论它如何混淆比特,我认为原则上你总是可以填充任何被抛弃的比特,例如常量零。但我想,函数的本质使得你不能简单地反转每一步。一个说“乘2再加5”的算法很容易通过减去5并除以2来反转。但更复杂的操作可能难以这样逐步反转。总有一天我会真正去学习这个算法。当我四处闲逛时。 - Jay
1
加密哈希函数必须具备以下几个属性:1)对于任何给定的消息,计算哈希值很容易;2)找到一个具有给定哈希的消息是不可行的;3)在没有改变哈希的情况下修改消息是不可行的;4)找到两个具有相同哈希的不同消息是不可行的。(来源:http://en.wikipedia.org/wiki/Cryptographic_hash_function)还有其他哈希函数,它们没有这些属性,因此在密码学中不使用。 - Peter Štibraný
换句话说,这并非“绝对不可能”(有些人正在尝试),但也不是轻而易举的事情。查看一下维基百科页面,你会发现一些之前使用的加密哈希函数已经被成功攻击了(例如,存在找到另一个具有相同哈希值的消息的方法),因此不再使用(寻找“碰撞攻击”和“预像攻击”)。 - Peter Štibraný

1
同样,由于多个字符串可以创建相同的MD5哈希值,因为它比输入字符串少了一些数据,那么任何其他哈希系统怎么会更好呢?
虽然存在多个(甚至是无限多个)具有相同哈希值的消息,但密码哈希的目标是使查找这种冲突变得不可行。
您可能认为可以通过计算随机消息的哈希值来找到冲突,直到最终两次获得相同的结果。但是,您低估了可能哈希值空间的大小。
对于MD5,哈希的大小为128位。 128位空间非常大。真的很大。你简直无法想象它有多么巨大。可能的哈希数是2的128次方,即3.40282367×10的38次方。这是一个后面跟着37个零的34!如果您可以在一秒钟内数到一万亿,则仍需要花费1000亿年才能数完所有128位数字。

然而,一些哈希算法(如MD5)存在弱点,允许攻击者以比暴力破解尝试更少的努力来反转它(即找到具有给定哈希的消息)。在这方面,MD5被认为是完全破碎的。


即使是谷歌也能帮上忙:http://md5crack.com/ - Pascal Thivent

1
考虑以下函数:f(x) = xx。现在,假设你知道f(x)=25,那么x是多少呢?嗯,答案可能是5,也可能是-5。你无法恢复f的输入,因为在f的范围内存在某些值,使得f的定义域中的多个元素映射到该值下的f。因此,函数f是不可逆的。相同的概念也适用于MD5;MD5算法有多个输入,尽管它们是不同的输入,但会产生相同的哈希值。换句话说,MD5算法,就像f(x)=xx一样,不是一对一的,因此不是可逆函数。

然而,这并不意味着您不能恢复MD5的输入。它只是意味着您不能以100%的确定性恢复MD5的输入。为了使这更具体化,让我们再次看一下函数f(x)= x * x。现在,如果我告诉您对于f的任何给定输入,它为正数的概率为99%,那么在这种情况下,您可以非常好地猜测25的哈希值来自5而不是-5的值。这确实是人们能够破解哈希函数(包括MD5,事实证明它不是一个非常好的加密哈希函数)的方法。当涉及密码时,有些密码比其他密码使用得更频繁。您只需要获取这些密码的MD5并将其与某些哈希进行比较,如果它们匹配,则可以合理地猜测它来自该密码。

您可能也对阅读以下内容感兴趣:一对一函数, 单射函数, 密码哈希函数, MD5, SHA1, 以及来自Benlog安全博客的不要哈希机密信息


1
此外,由于多个字符串可以创建相同的MD5哈希值,因为它的数据比输入字符串少,那么任何其他散列系统会更好吗?
已知对MD5进行了攻击,使得攻击者能够创建具有不同内容但相同MD5哈希值的多个文档。这种攻击是可计算的,并作为演示之用,被用来“预测”总统选举结果。(攻击者在选举前发布一个哈希值,然后在选举后公布具有相同哈希值的给出胜者名称的文件。但实际上,攻击者有每个候选人的文档,所有这些文档都具有相同的哈希值。)
更好的系统将提供加密保证,即创建两个散列为相同值的不同文档在计算上无法完成。SHA-1可以是这样的一个系统。

更糟糕的系统将允许攻击者通过获得任何哈希来创建具有该哈希的文档。备受尊敬的CRC系统仍在许多硬件系统(例如以太网)中使用,容易受到此类攻击。与MD5一样,它是一种哈希函数,其输出无法从输入重构,但是给定任何输出,都可以轻松构造具有给定CRC-32或CRC-64签名的文档。更糟糕的是,您可以在这样的文档中放置任何文本,然后通过在末尾添加垃圾来获取所需的CRC。

CRC-32可以非常快速地计算,MD5需要更长时间,而SHA-1需要比MD5更长的时间。成本模型和信任模型都很困难。

一个真正好的哈希函数应该像CRC一样快速计算,并且像SHA-1一样难以构造两个文档的哈希值相同。不要抱太大希望...


2
实际上,CRC-32并不是那么快的;在某些系统(例如ARM),一些哈希函数(MD4、Panama等)比CRC-32更快。CRC-32在硬件方面非常快,作为电路,但在软件中实现时,必须使用查找表,而许多RISC处理器对表格相当不舒服。 - Thomas Pornin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接