能否解密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个回答

462

不,MD5不是加密(尽管它可能作为某些加密算法的一部分),它是单向哈希函数。在转换的过程中,实际上会丢失原始数据的大部分信息。

想象一下:一个MD5值总是由128个比特位组成。这意味着有2128种可能的MD5哈希值。虽然这是一个相当大的数字,但肯定是有限的。而且,对于给定的哈希函数来说,有无数个可能的输入(大多数包含超过128比特位或仅仅16字节的微不足道数据)。因此,实际上有无限多的数据可以映射到相同的哈希值。哈希函数的有趣之处在于,要找到两个具有相同哈希值的数据非常困难,而且碰巧发生的几率几乎为零。

一个简单的例子是一个(非常不安全的)哈希函数(这说明了单向哈希的一般思想):将所有数据的比特位全部取出,将其视为一个大数字。接下来,使用一些大的(可能是质数)数字n进行整数除法,并取余数(请参见:模算术)。这样将得到0到n之间的某个数字。如果你再次执行相同的计算(任何时间、任何地方的任何计算机),使用完全相同的字符串,将得到相同的值。但是,没有办法找出原始值是什么,因为有无限多的数字在除以n的时候都会产生相同的余数。

尽管如此,MD5算法被发现存在一些弱点,使用一些复杂的数学方法可能会在不尝试2128个可能的输入字符串的情况下找到碰撞。而且,由于大多数密码长度很短,人们经常使用常见值(例如“password”或“secret”),这意味着在某些情况下,通过搜索哈希或使用Rainbow表,你可以对某人的密码进行合理的猜测。这就是为什么你应该始终为已哈希的密码“加盐”,以便两个相同的值在哈希后将不会哈希成相同的值的一个原因。

一旦数据经过哈希函数处理,就无法逆转。


26
然而,在 MD5 哈希空间中发生的碰撞比最初预计的要多。因此,它不再被认为是密码哈希的最佳选择。 - Cheeso
14
由于大多数密码比MD5散列短,因此通常每个哈希只有一个密码。(即使找到一个不是原始密码的密码也足以访问帐户。)单向函数的重点不在于“存在多个不同的原像,因此我们无法知道哪一个是原始值”,而在于“即使找到一个原始值也非常困难”。 - Paŭlo Ebermann
2
@Nick:实际上,RFC1321明确指出:“该算法以任意长度的消息作为输入”。 - Adam Batkin
7
@Olathe - 我不确定我同意。给定一个哈希值,通常无法确定(百分之百确定)原始输入。通常有无穷多个输入会产生每个可能的(散列)输出。我说“通常”是因为,如果您知道(例如)要查找ASCII字符串并且长度小于12个字节,则可能只有一个输入可以产生给定的输出。但总会存在碰撞(无限),除非您有某些外部约束条件(例如我的示例),否则您永远无法确定哪一个是正确的。 - Adam Batkin
2
@Adam Batkin,你是对的,但我并不意味着100%的确定性。密码破解不能以100%的确定性完成。发送者可能指的是随机无意义字符串,而不是使用相同密钥解密其他英文明文的英文明文,但英文的概率非常接近于100%。同样,当选择长的UTF-8日语诗歌密码和乱码字符串时,诗歌的概率接近于100%。这可以使用事后概率而不是预先选择的约束条件来完成。显然,这不能普遍适用,但仍然非常有用。 - Olathe
显示剩余5条评论

161
理论上是不可能的。哈希的整个意义在于它是单向的。这意味着,如果有人设法获得哈希列表,他们仍然无法获得您的密码。另外,这也意味着即使有人在多个网站上使用相同的密码(是的,我们都知道我们不应该这样做,但...),访问网站A数据库的任何人也无法在网站B上使用用户的密码。
MD5是一种哈希函数,这意味着它会丢失信息。对于给定的MD5哈希值,如果允许任意长度的密码,则可能有多个密码生成相同的哈希值。对于一个好的哈希函数来说,找到超出一定长度的密码将是计算上不可行的,但这意味着不能保证如果您找到一个具有目标哈希值的密码,它就一定是原始密码。看到两个ASCII字符,长度合理的密码具有相同的MD5哈希值是天文数字级别的不太可能事件,但并非不可能。
MD5是用于密码不安全的哈希函数:
  • 它很快,这意味着如果你有一个“目标”哈希值,可以很容易地尝试很多密码并查看是否可以找到一个哈希为目标哈希值的密码。加盐不能帮助那种情况,但它有助于使尝试查找与不同盐使用的多个哈希之一匹配的密码更加昂贵。
  • 我相信它有已知的漏洞,这使得发现碰撞更加容易,尽管在可打印文本(而不是任意二进制数据)内找到碰撞至少会更难。
我不是安全专家,因此不会做出具体建议,只能说“不要自己编写身份验证系统。”从值得信赖的供应商处寻找一个身份验证系统,并使用它。设计和实施安全系统都是棘手的事情。

2
是的,还有其他方法,但你需要理解Jon上面所说的 - “你不应该通过电子邮件发送密码 - 那是敏感信息,可能会一直保持敏感。” - 在最低层次上,电子邮件可以被拦截,敏感信息可以被检索。密码应该尽可能地保密 - 通常只在数据库中保留哈希值。 - Daniel May
3
如果密码可以被反转,这意味着任何能够访问数据库的人都可以获取用户的密码,这不是一个好主意。单向密码应该成为常态;只有在绝对必要的情况下(例如需要使用另一种基于令牌的系统进行身份验证)才会保留真实密码(即使已加密)。 - Jon Skeet
1
我见过反垃圾邮件措施,其中接收方的 Web 服务器拒绝传入的邮件,只是为了等待发件人的邮件服务器重试(垃圾邮件机器通常只尝试一次)。这可能超过您的 10 分钟超时。 - sisve
1
@ravisoni:这是通过暴力破解或查找表来寻找具有相同哈希值的一个值。不能保证它是原始明文值。 - Jon Skeet
5
“right”在这里是什么意思?如果密码不知道,就不能确定所揭示的密码是否为原始密码。但关键是单向哈希函数如MD5“按定义”会丢失信息。像这样的网站能够提供“一个”匹配密码的事实只是MD5作为安全算法使用不当的很好证据。 - Jon Skeet
显示剩余7条评论

55

从技术上讲,这是“可能的”,但需要在非常严格的条件下彩虹表,基于用户密码在哈希数据库中的非常小的可能性进行暴力破解)。

但这并不意味着它是

  • 可行的
    或者
  • 安全的

你不想“反向”MD5哈希。使用下面概述的方法,你永远不需要这样做。“反向”MD5实际上被认为是恶意的——一些网站提供“破解”和暴力破解MD5哈希的能力——但它们只是包含字典单词、以前提交的密码和其他单词的大型数据库。它有非常小的机会拥有你需要反转的MD5哈希。如果你已经加盐了MD5哈希——这也行不通!:)


使用MD5哈希的登录方式应该是这样的:

注册期间:
用户创建密码 -> 密码使用MD5进行哈希 -> 哈希存储在数据库中

登录期间:
用户输入用户名和密码 -> (检查用户名)密码使用MD5进行哈希 -> 将哈希与数据库中存储的哈希进行比较

当需要“忘记密码”时:

2个选项:

  • 向用户发送一个随机密码以登录,然后在第一次登录时提示用户更改密码。

或者

  • 向用户发送一个更改密码的链接(如果您有安全问题等额外检查),然后将新密码哈希并替换旧密码在数据库中

1
我有一些小问题。 彩虹表不是暴力破解。 实际上,有一些程序和网站可以对几个字符的(非常简单)密码进行暴力破解(通常只需循环几个小时或几天,您可以填写哈希并希望它在循环中出现)。 不幸的是,鉴于许多密码的质量不高,其中一个弹出的机会并不是“非常小的机会”。 - Maarten Bodewes
我必须插话一句:反向MD5本质上并不是恶意的。你如何使用这种能力决定了恶意或善意。如果有人发现如何反向它并与世界分享,他们可能会赢得诺贝尔奖或其他什么奖项。如果你想要尝试反向工程任何东西,绝对不要害怕。这就是我们所有人变得更好的方式。但是,如果你找到了MD5的反向方法,然后将其用于个人利益,那么你就是在做恶。 - Robert Cotterman

32

不能直接反向计算。由于鸽巢原理,任何给定的MD5输出可能有多个值对应。因此,您无法确定地反转它。此外,MD5被设计成使查找任何反转哈希都很困难(但已经有攻击产生了碰撞 - 即生成两个值得到相同结果的哈希,但您无法控制结果的MD5值)。

但是,如果将搜索空间限制在长度小于N的常见密码上,您可能不再具有不可逆性质(因为MD5输出数量比感兴趣的字符串域中的数量要大得多)。然后,您可以使用彩虹表或类似工具来反向哈希。


1
我想补充一点,找到另一个与同样输出哈希的值被称为“碰撞”。这是破解MD5哈希系统最常用的方法。 - Nicole
5
@Renesis,“预像”是指找到与先前已知值哈希相同的数据,实际上,这比发生冲突要难得多。目前尚未展示出针对MD5的预像攻击,但已经有冲突攻击被使用。 - bdonlan
哈希函数(用于密码存储时)的重点不在于有很多可能产生相同哈希值的密码(确实有,但大多数比哈希本身还长),而是很难找到其中任何一个(这就足以访问系统)。是的,由于彩虹表,您不会使用未加盐的哈希。由于密码空间较小,您将使用慢哈希(如bcrypt或scrypt)而不是快哈希(如MD5 / SHA- * / ...)。 - Paŭlo Ebermann
1
从技术上讲,你不能百分之百地执行MD5,因为硬件可能出现故障。同样地,你可能无法确定密码是“password”,而不是所有产生相同哈希值的无限输入,这些输入看起来都很随机,但你可以接近确定。 - Olathe
鸽巢原理当然适用,但找到第二个输入散列为某个值仍然是计算上不可行的,例如普通密码的哈希。如果你找到一个X散列为给定的H(X),那么你可以确定X是正确的输入。这使得本回答的整个第一部分和大部分其他内容都是不正确的。 - Maarten Bodewes

13

不可能,在合理的时间内不可能。

通常处理方式是进行密码“重置”。也就是说,您会为其生成新的(随机的)密码并通过电子邮件发送给他们。


5
如果哈希值没有被加盐,你会惊讶地发现只需进行一次谷歌搜索就能得到哈希值的明文。 - Michael Borgwardt
1
虽然对于密码恢复系统来说并不是很实用,甚至包括未经盐处理的情况 :) - Matthew Groves

12

无论使用什么语言,你都无法恢复一个MD5密码。

但是你可以:

为用户提供一个新的密码。

在彩虹表中检查以尝试检索旧密码。


1
放弃彩虹表的想法。如果您正在进行加盐(而且您应该这样做),那么它也不会起作用。 - Steven Sudit
1
如果他们仍在使用MD5来哈希密码而不是使用强密码哈希,那么你不能假设他们正在使用盐。也许他们这样做了,可能他们没有。 - Maarten Bodewes

10

不,他一定是对MD5字典混淆了。

密码哈希 (如MD5等) 是单向的,只有摘要信息是无法还原为原始消息的,除非你拥有关于原始消息的其他信息等。

但这需要保密,否则会导致安全风险。


8

解密(直接从哈希值中以算法的方式获取明文),不行。

然而,有一些方法使用所谓的彩虹表。如果您的密码没有加盐进行哈希处理,则这种方法相当可行。


7

MD5是一种哈希算法,你不能还原哈希值。

你应该添加“修改密码功能”,用户提供另一个密码,计算哈希并将其存储为新密码。


7

这并不是一件容易的事情,这也是首次对密码进行哈希处理的原因 :)

你应该能够做的一件事情是为他们手动设置一个临时密码并将其发送给他们。

我犹豫要不要提及这个方法,因为这是一个不好的想法(而且也不能保证一定有效),但你可以尝试像milw0rm这样的彩虹表中查找哈希值,以此来恢复旧密码。


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