是否有可能解密MD5哈希?

Joh*_*ski 250 encryption hash md5 cryptography

有人告诉我他见过软件系统:

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

那可能吗?我认为解密MD5哈希是不可能/不可行的.

我知道有MD5词典,但是有没有实际的解密算法?

Ada*_*kin 410

MD5不是加密(尽管它可以用作某些加密算法的一部分),它是一种单向散列函数.许多原始数据实际上是"失去"作为转型的一部分.

想一想:MD5总是128位长.这意味着有2 128个可能的MD5哈希值.这是一个相当大的数字,但它绝对是有限的.然而,给定的散列函数有无数个可能的输入(并且它们中的大多数包含超过128位,或者只有16个字节).因此,对于将散列到相同值的数据实际上存在无限多种可能性.使哈希变得有趣的是,找到两个散布到相同值的数据是非常困难的,并且偶然发生的几率几乎为0.

(非常不安全)哈希函数的一个简单示例(这说明它是单向的一般概念)是获取一段数据的所有位,并将其视为大数.接下来,使用一些大的(可能是素数)数字n执行整数除法并取余数(参见:模数).您将在0和n之间留下一些数字.如果您再次执行相同的计算(任何时间,在任何计算机上,任何地方),使用完全相同的字符串,它将提供相同的值.然而,没有办法找出原始值是什么,因为有无数个数字具有精确的余数,除以n.

也就是说,已发现MD5存在一些弱点,因此通过一些复杂的数学运算,有可能在不尝试输入2 128个输入字符串的情况下找到碰撞.事实上,大多数密码都很短,而且人们经常使用常用值(如"密码"或"秘密")意味着在某些情况下,您可以通过Google搜索哈希或使用彩虹对某人的密码做出相当好的猜测桌子.这就是为什么你应该总是" 加盐 "散列密码的一个原因,这样两个相同的值在散列时不会散列到相同的值.

一旦数据通过哈希函数运行,就不会再回头了.

  • 但是,MD5哈希空间中的冲突比最初想象的要多.它不再被认为是最佳的密码哈希值. (22认同)
  • 由于大多数密码都比MD5哈希短,因此每个哈希通常只有一个密码.(找到一个,即使它不是原始的,也足以访问该帐户.)单向函数的关键不是*有多个不同的preimages,所以我们不知道哪个是原始的一个*,但*很难找到一个原始值*. (11认同)
  • @Olathe - 我不确定我是否同意.给定哈希值,通常*不可能确定(100%确定)原始输入.(通常)有无限数量的输入产生每个可能的(散列)输出.我说*通常*因为,如果你知道(例如)你正在寻找一串ASCII字符,并且它比12字节少,那么很可能只有一个输入产生给定的输出.但总有冲突(无限),除非你有一些外部约束(比如我的例子),你永远不会知道哪个是正确的 (5认同)
  • @Nick:实际上,RFC1321明确地说:"算法将任意长度的消息作为输入" (2认同)
  • @Adam Batkin,你是对的,但我并不是说100%确定.无法100%确定地进行密码破解.发送者可能意味着随机乱码而不是英文明文使用相同的密钥来解密其他英文明文,但英语的概率非常接近100%.同样,当选择长UTF-8日本诗密码和乱码字时,这首诗的概率接近100%.这可以使用事后概率而不是预先选择的约束来完成.它显然不能一般地完成,但它仍然非常有用. (2认同)

Jon*_*eet 154

你不能 - 理论上.哈希的全部意义在于它只是一种方式.这意味着如果有人设法获取哈希列表,他们仍然无法获取您的密码.此外,这意味着即使有人在多个站点上使用相同的密码(是的,我们都知道我们不应该,但是......)任何有权访问站点A数据库的人都无法使用用户的密码网站B.

MD5是哈希的事实也意味着它丢失了信息.对于任何给定的MD5哈希,如果允许任意长度的密码,可能会有多个密码产生相同的哈希值.对于一个好的哈希,在计算上不可能找到它们超出一个非常微不足道的最大长度,但这意味着不能保证如果你找到一个具有目标哈希的密码,它肯定是原始密码.这是天文数字不可能,你会看到具有相同的MD5哈希两个ASCII-只,合理的长密码,但是这不是不可能的.

MD5是用于密码的错误哈希:

  • 这很快,这意味着如果你有一个"目标"哈希,尝试大量密码并看看你是否可以找到一个哈希到那个目标的便宜.Salting对这种情况没有帮助,但是尝试使用不同的盐找到与多个哈希中的任何一个匹配的密码会使其变得更加昂贵.
  • 虽然在可打印文本(而不是任意二进制数据)中找到碰撞至少会更难,但我相信它已知存在使得更容易找到碰撞的缺陷.

我不是安全专家,因此除了"不要推出自己的身份验证系统"之外,不会提出具体建议.从信誉良好的供应商那里找到一个,并使用它.安全系统的设计和实现都是一项棘手的工作.

  • @ravisoni:这里的"正确"是什么意思?如果密码未知,您无法知道显示的密码是否是原始密码.但问题是,根据定义,像MD5*这样的单向散列*会丢失信息.像这样的网站可以提供*a*匹配密码的事实只是MD5作为安全原因使用的不良算法的良好证据. (5认同)
  • 而且如果密码可以反转,这意味着任何能够访问您的数据库的人都可以获得用户的密码.*不是一个好主意.密码的一种方式应该是常态; 只保留真实密码(甚至是加密的),如果你绝对*有*(例如,用另一个没有任何基于令牌的系统进行身份验证). (3认同)
  • 是的,还有其他方法,但你需要了解Jon上面所说的 - "你不应该通过电子邮件向他们发送密码 - 这些敏感信息可能仍然敏感." - 在最低级别,可以拦截电子邮件并检索敏感信息.密码应尽可能保持安全 - 通常只将其保存为数据库中的哈希值. (2认同)

Dan*_*May 53

从技术上讲,它是"可能的",但是在非常严格的条件下(彩虹表,基于用户密码在该哈希数据库中的极小可能性的暴力强制).

但这并不意味着它

  • 可行
  • 安全

您不希望"反转" MD5哈希.使用下面列出的方法,您将永远不需要."逆转"MD5实际上被认为是恶意的 - 一些网站提供了"破解"和暴力破解MD5哈希的能力 - 但它们都是包含字典单词,以前提交的密码和其他单词的大型数据库.有一个非常小的机会,这将有你需要扭转的MD5哈希值.如果你已经腌制了MD5哈希 - 这也不行!:)


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

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

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

当需要'忘记密码'时:

2个选项:

  • 用户发送随机密码登录,然后在第一次登录时更改密码.

要么

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


bdo*_*lan 32

不是直接的.由于鸽笼原理,(可能)有多个值可以对任何给定的MD5输出进行哈希处理.因此,你无法肯定地扭转它.此外,MD5使得很难找到任何这样的反向散列(但是存在产生冲突的攻击- 也就是说,产生两个散列到相同结果的值,但是你无法控制得到的MD5值将会是什么是).

但是,如果将搜索空间限制为长度小于N的常用密码,则可能不再具有不可逆性属性(因为MD5输出的数量远远大于感兴趣域中的字符串数).然后你可以使用彩虹表或类似的反向哈希.

  • @Renesis,找到散列到先前已知值的数据实际上被称为"preimage",并且它比碰撞更难,更难.目前还没有针对MD5证明过原始图像攻击,但已经使用了碰撞攻击. (5认同)

Mat*_*ves 13

不可能,至少在合理的时间内没有.

通常处理的方式是密码"重置".也就是说,您给他们一个新的(随机)密码并将其发送到电子邮件中.

  • 如果哈希没有被腌制,你会惊讶地发现所有需要的是谷歌搜索哈希值...... (5认同)

Net*_*rof 12

您无法还原md5密码.(使用任何语言)

但是你可以:

给用户一个新的.

检查一些彩虹表可能检索旧的.


Rob*_*ner 10

不,他一定对MD5词典感到困惑.

加密哈希(MD5等)是一种方法,除非您有关于原始邮件等的其他信息,否则您无法仅使用摘要回复原始邮件.


Sin*_*our 8

解密(以算法的方式直接从散列值中获取纯文本),否.

然而,有一些方法使用所谓的彩虹表.如果您的密码是在没有盐的情况下进行哈希处理,那将非常可行


Sve*_*lov 7

MD5是一种哈希算法,您无法还原哈希值.

您应该添加"更改密码功能",其中用户提供另一个密码,计算哈希值并将其存储为新密码.


Bil*_*ard 7

没有简单的方法可以做到这一点.这是首先对密码进行哈希处理的一点.:)

应该能够做的一件事是手动为它们设置临时密码并将其发送给它们.

我不愿提及这个,因为它是一个坏主意(并且无论如何都无法保证工作),但你可以尝试在像彩虹表这样的反汇编中查找哈希,看看你是否能以这种方式恢复旧密码.


Din*_*nah 6

在这里查看所有其他答案,关于它是如何以及为什么它不可逆,以及为什么你不想要.

为了完整,有彩虹表,你可以查找可能匹配.无法保证彩虹表中的答案将是您的用户选择的原始密码,因此会极大地混淆它们.

此外,这不适用于盐渍哈希.许多安全专家建议使用盐腌.

  • @MaartenBodewes:但是“天文上不可能”和“不可能”之间存在很大差异。IMO,你关于它*确定*它是正确密码的声明过于强大。这表明不存在的数学确定性。 (2认同)

Maa*_*wes 6

不,不可能反转 MD5 等哈希函数:给定输出哈希值,除非已知有关输入消息的足够信息,否则不可能找到输入消息。

解密不是为哈希函数定义的函数;加密和解密是密码的功能,例如 CBC 模式下的 AES;哈希函数不加密也不解密哈希函数用于消化输入消息。顾名思义,设计上不可能存在逆向算法。


MD5 被设计为一种加密安全的单向哈希函数。现在很容易生成 MD5 冲突 - 即使输入消息的很大一部分是预先确定的。因此,MD5 已正式被破解,MD5 不应再被视为加密安全哈希。然而,仍然不可能找到导致哈希值的输入消息:当仅知道 H(X) 时找到 X(并且 X 不具有包含至少一个 128 字节预计算数据块的预计算结构) 。目前还没有针对 MD5 的已知原像攻击

通常也可以使用暴力或(增强)字典攻击来猜测密码,比较数据库或尝试在所谓的彩虹表中查找密码哈希值。如果找到匹配,则在计算上可以确定已找到输入。散列函数还可以防止碰撞攻击:查找给定X'的。因此,如果找到了,则可以通过计算确定它确实是输入消息。否则你毕竟会执行碰撞攻击。彩虹表可用于加速攻击,并且有专门的互联网资源可以帮助您找到给定特定哈希值的密码。H(X') = H(X)H(X)X

当然可以重新使用哈希值H(X)来验证在其他系统上生成的密码。接收系统唯一要做的就是存储作为输入F的确定性函数的结果H(X)。WhenX被提供给系统 thenH(X)并因此F可以重新计算并且可以比较结果。换句话说,不需要解密哈希值来验证密码是否正确,并且您仍然可以将哈希值存储为不同的值。


重要的是使用密码散列或 PBKDF(基于密码的密钥派生函数)来代替 MD5。这样的函数指定如何将与哈希值一起使用。这样,就不会为相同的密码(来自其他用户或其他数据库内)生成相同的哈希值。由于这个原因,只要盐足够大并且正确随机化,密码哈希也不允许使用彩虹表。

密码哈希还包含一个工作因素(有时使用迭代计数进行配置),可以显着减缓尝试在给定盐和哈希值的情况下查找密码的攻击。这很重要,因为包含盐和哈希值的数据库可能会被盗。最后,密码散列也可能是内存困难的,因此需要大量的内存来计算散列。这使得攻击者无法使用特殊硬件(GPU、ASIC、FPGA 等)来加速搜索。其他输入或配置选项(例如胡椒或并行化量)也可用于密码散列。

然而,它仍然允许任何人验证给定的密码,H(X)即使是H(X)密码哈希。密码哈希仍然是确定性的,因此如果任何人知道所有输入和哈希算法本身,则X可以用于计算H(X),并且可以再次比较结果。

常用的密码哈希是bcryptscryptPBKDF2。还有各种形式的Argon2,它是最近密码哈希竞赛的获胜者。CrackStation 上有一篇关于正确保护密码安全的好博客文章。


有可能使对手无法执行哈希计算来验证密码是否正确。为此,可以使用胡椒作为密码哈希的输入。或者,当然可以使用诸如AES之类的密码和诸如CBC或GCM之类的操作模式来对哈希值进行加密。然而,这需要独立存储秘密/密钥,并且具有比密码散列更高的访问要求。