能否解密MD5哈希值?

289

有人告诉我,他看到过软件系统:

  1. 从其他系统中检索MD5加密密码;
  2. 解密加密的密码并且
  3. 使用该系统自己的算法将密码存储在系统数据库中。

这种情况可能吗? 我原以为无法解密MD5哈希。

我知道有MD5字典,但是否存在实际的解密算法呢?


9
还原MD5会产生多个密码。 - Carles Company
285
MD5 是一种摘要算法。可以将其想象成将一头牛变成牛排。现在试图反转这个过程。 - Mechanical snail
5
据我理解,是的,但前提是你必须有大量这样的东西。即使你有大量的这些东西,你也无法进行反向操作,因为该算法故意丢失信息。 - Jordan
10
鉴于这个比喻,人们可以从牛排上的DNA完美地克隆出一份完全相同的复制品。 :)) - Trimikha Valentius
10
MD5是一种摘要算法。把它想象成吃牛排>消化>输出的过程。现在试着反过来做。 - user4157124
显示剩余6条评论
24个回答

6
不,无法反向计算哈希函数(如MD5):除非已知有关输入消息的足够信息,否则不可能找到输入消息。解密不是哈希函数的定义范畴;加密和解密是密码(如CBC模式中的AES)的功能;哈希函数既不加密也不解密。哈希函数用于摘要输入消息。顾名思义,设计上没有可逆算法。
MD5被设计为安全的单向哈希函数。现在很容易生成MD5的冲突 - 即使大部分输入消息已经确定。因此,MD5已经被攻破,不能再被认为是安全的哈希函数了。但仍然不可能找到导致哈希值的输入消息:当只知道H(X)时找到X是不可能的(且X没有至少一个预计算数据块长度为128字节的预先计算结构)。对于MD5,没有已知的预像攻击。
通常可以使用暴力破解或(增强的)字典攻击来猜测密码,比较数据库或尝试在所谓的彩虹表中找到密码哈希。如果找到匹配项,则可以计算出输入已被找到。哈希函数也能抵御碰撞攻击:找到X',使得给定H(X)时H(X')= H(X)。因此,如果找到X,则可以确定它确实是输入消息。否则,你最终执行的将是碰撞攻击。彩虹表可用于加快攻击速度,并且有专门的互联网资源可帮助您在给定特定哈希时查找密码。
当然,可以重复使用哈希值H(X)来验证在其他系统上生成的密码。接收系统唯一需要做的就是存储确定性函数F的结果,该函数以H(X)作为输入。当给出X时,可以重新计算H(X),因此也可以重新计算F,并比较结果。换句话说,只需验证密码是否正确,而不必解密哈希值,仍然可以将哈希值存储为不同的值。
使用密码哈希或PBKDF(基于密码的密钥派生函数)来代替MD5非常重要。这种函数指定如何与哈希一起使用。这样,对于相同的密码(来自其他用户或其他数据库),不会生成相同的哈希值,因此也不允许使用彩虹表。只要盐足够大且随机化得足够好,密码哈希也不允许使用彩虹表。
密码哈希还包含一个工作因素(有时使用迭代次数进行配置),可以大大减缓试图查找给定盐和哈希值的密码的攻击速度。这很重要,因为带有盐和哈希值的数据库可能会被窃取。最后,密码哈希也可能是内存硬化的,因此需要大量内存来计算哈希。这使得使用特殊硬件(GPU、ASIC、FPGA 等)加速搜索的攻击者无法实现。密码哈希还可以提供其他输入或配置选项,如pepper或并行化数量。
然而,仍然可以使用H(X)验证密码是否正确,即使H(X)是密码哈希。密码哈希仍然是确定性的,因此如果任何人都知道所有输入和哈希算法本身,那么X可用于计算H(X),结果可以进行比较。
常用的密码哈希有bcryptscryptPBKDF2。还有各种形式的Argon2,它是最近的密码哈希竞赛的获胜者。这里的CrackStation是一篇关于正确进行密码安全的好博客文章。
可以使用pepper作为密码哈希的输入,以使对手无法执行哈希计算来验证密码是否正确。或者,当然可以使用诸如AES之类的密码算法以及CBC或GCM之类的操作模式来加密哈希值。但是,这需要独立存储一个秘密/密钥,并具有比密码哈希更高的访问要求。

6
请查看其他回答,了解为什么无法反转以及你不应该这样做的原因。
但是为了完整起见,有彩虹表可以查找可能的匹配项。不能保证彩虹表中的答案就是用户选择的原始密码,这会使他们感到困惑。
此外,这对于加盐哈希将不起作用。 许多安全专家建议加盐。

如果找到匹配,则可以确定它是原始密码。如果不是这种情况,那么在对手没有预定义结构的消息X中生成碰撞是可能的。对于加密安全哈希函数来说,即使它是像MD5这样的已破解哈希函数,找到这样的碰撞也是计算上不可行的。 - Maarten Bodewes
@MaartenBodewes:“如果找到匹配项,则肯定是原始密码。”我不明白这是怎么回事,如果我们假设密码长度无限制。我会说这极有可能是原始密码,但不一定非要是。事实上,可能存在两个具有相同哈希值的密码,因为可能的密码数量比MD5哈希值多。仅仅因为计算上难以找到这样的碰撞,并不意味着它们不存在。或者我误解了你的意思? - Jon Skeet
@JonSkeet 如果故意找到碰撞在计算上是不可行的,那么通过偶然找到碰撞的概率同样不大或更小。由于MD5的输出空间有限以及生日问题,您找到碰撞的机会约为2^64分之1(即输出空间的一半左右),而这是在匹配约2^64个哈希值之后。而且,这甚至没有考虑到消息可能需要很小并具有特定格式才能被视为密码。大多数密码的熵远低于2^64位。 - Maarten Bodewes
2
@MaartenBodewes:但是“天文数字的不可能性”和“不可能”之间有很大的区别。我认为你关于这一定是正确密码的说法过于强烈了。这表明了一种不存在的数学确定性。 - Jon Skeet
你也可以一次性猜测一个2^128位的AES密钥。只是这种情况发生的概率极小。密码学依赖于这种概率。就所有实际目的而言,如果你找到了一个输入消息/密码,那么它就是你要找的那个。理论上可能会找到另一个输入消息,但对于这个StackOverflow问题来说,没有必要考虑这一点。彩虹表只包含可能的密码。它们不会包含足够的数据,以至于永远不会发生碰撞(它们要么无意中覆盖映射,要么变得出名)。 - Maarten Bodewes

4

您可以找到在线工具,使用字典来检索原始消息。

在某些情况下,字典方法可能是无用的:

  • 如果消息使用SALT消息进行哈希处理
  • 如果消息被多次哈希处理

例如,这里有一个MD5解密器在线工具。


如果使用了盐值,彩虹表攻击就无效了,而不是字典攻击。如果没有使用盐值,多次哈希仍然允许使用彩虹表,尽管在线查找预先存在的彩虹表的可能性肯定较小。 - Maarten Bodewes

4
没有办法“还原”哈希函数,也就是找到它的反函数。正如之前提到的,这就是哈希函数的全部意义所在。它不应该是可逆的,并且应该允许快速计算哈希值。因此,找到一个产生给定哈希值的输入字符串的唯一方法是尝试所有可能的组合。由于这个原因,这被称为暴力攻击。
尝试所有可能的组合需要很长时间,这也是为什么哈希值用于相对安全地存储密码的原因。如果攻击者能够访问您的数据库并获取其中所有用户密码,那么您无论如何都会失败。如果您有哈希值和(理想情况下)强密码,则对于攻击者来说,从哈希值中获取密码将更加困难。
存储哈希值也不是性能问题,因为计算哈希值相对较快。因此,大多数系统所做的就是计算用户输入的密码的哈希值(这是快速的),然后将其与其用户数据库中存储的哈希值进行比较。

这个答案没有太大的问题,除了哈希函数的速度确实是一个问题,因为大多数密码不够安全,允许对手执行字典攻击。因此,使用缓慢的密码哈希函数代替快速的加密安全哈希函数。 - Maarten Bodewes

4

MD5 被认为是不安全的,不是因为你可以从哈希中获取原始内容,而是因为通过工作,你可以制作出两个消息并且它们会哈希到相同的哈希值。

你无法对一个 MD5 哈希进行反向操作。


5
所有长度相同的哈希函数设计上都会存在碰撞问题。这是由于它们必须处理可变长度的数据所导致的。MD5被认为已经过时,主要是因为其碰撞出现的频率,并非因为其具有碰撞问题的事实。 - Jonathan Lonowski
1
MD5因已被证明存在构造输入碰撞的可能性而被认为是不安全的。 - Ned Batchelder

2

唯一可行的方法是使用字典攻击工具(如果我们提到密码只是经过哈希处理,没有添加任何种类的盐以防止重放攻击,如果是这样,您必须知道盐值),获取许多单词、数字等文件,然后创建两行,一行是单词、数字(在字典中),另一行是单词的哈希值,并比较哈希值,如果匹配则找到了密码...

这是唯一的方法,而不需要进行密码分析。


2
MD5哈希算法不可逆,因此无法进行MD5解码,但是一些网站具有大量密码匹配集,因此您可以尝试在线解码MD5哈希。

在线尝试:

MD5解密

md5在线解密

md5解密器


是的,但这已经被问题中的短语“我知道有字典”覆盖了。所以仅仅指出字典并不算作一个答案。 - Maarten Bodewes

2
是的,您所要求的确实是可能的。但是,在没有帮助的情况下,“解密”MD5密码是不可能的,但可以将MD5密码重新加密为另一种算法,只是不能一次完成所有操作。
您需要做的是安排用户能够使用旧的MD5密码登录到新系统。在登录时,他们已经向您的登录程序提供了密码的未加密版本,您可以证明它与您拥有的MD5哈希值匹配。然后,您可以将此未加密密码转换为新的哈希算法。
显然,这是一个扩展过程,因为您必须等待用户告诉您密码,但它确实有效。
(注:七年后,希望有人会发现它有用)

谢谢回复。不过我要“超越”你 :) 我不记得我是否真的这样做了,但理论上应该可以。不必等待每个用户登录以便我们重新加密他们的密码,而是可以简单地加密其密码的哈希版本。因此,每个密码都将被MD5哈希,然后加密。只需更新密码检查以执行相同操作,用户数据应该是安全的,无需用户干预。 - John B
我之前的评论还有一个需要注意的地方。我不是加密方面的专家,所以我不确定是否存在其他安全隐患。例如,在加密之前对弱哈希密码进行加密可能会危及加密的安全性(也许可以使用另一种盐?)。此外,你可能有备份中包含那些MD5哈希密码。在进行此类升级时最好对所有现有密码进行完全失效。 - John B
密码学家们担心双重加密,但我认为他们只发现了一些微不足道的情况。但我认为在这种情况下它并没有用处,因为MD5对于(不太长的)密码仍然是安全的。不过,如果之前的开发人员忘记添加盐,则双重哈希可能会有用,否则,我想不出还有哪种情况下你不必告诉每个人密码应该被视为已被入侵。希望您的备份不会丢失,并且无论如何都要进行加密。 - user3710044

1

MD5 有其弱点(参见维基百科),因此有一些项目试图预计算哈希值。维基百科也提到了其中的一些项目。我知道的一个(并且很尊重)是 ophrack。您不能告诉用户他们自己的密码,但您可能能够告诉他们一个有效的密码。但我认为:如果他们忘记了,请给他们发送一个新密码。


MD5被破解(对于函数的特定但重要用途)与彩虹表毫无关系(当您提到哈希的预计算时,这就是您在暗示的内容)。 - Maarten Bodewes

1
理论上来说,无法解密哈希值,但你可以使用一些不正当的技术来获取原始明文。
1. 暴力破解:所有计算机安全算法都会遭受暴力破解。基于这个想法,今天的GPU采用了并行编程的思想,使用任何图形处理器可以通过大规模暴力破解来获取明文。这个工具hashcat就是做这个事情的。上次我检查它的cuda版本时,我能够在六分钟内暴力破解一个7个字母长的字符。
2. 互联网搜索:只需将哈希复制并粘贴到Google上,看看是否可以在那里找到相应的明文。这不是渗透测试时的解决方案,但绝对值得一试。一些网站几乎为字典中的所有单词维护哈希。

2
字典攻击是另一种方式,或者与其他数据库进行比较,以了解输入密码。 - Maarten Bodewes

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