【问题标题】:How can it be impossible to "decrypt" an MD5 hash? [duplicate]怎么不可能“解密”一个 MD5 哈希? [复制]
【发布时间】:2011-02-12 15:52:33
【问题描述】:

可能重复:
How come MD5 hash values are not reversible?

我正在阅读一个关于 MD5 的问题,它让我想起了一些让我难以理解的事情。非常简单的问题,如果不是一个好问题,我很抱歉。我只是无法理解您如何使用某种算法将某物转换为某物,并且无法使用反向算法将其转换回来。

那么这怎么可能呢?

另外,由于多个字符串可以创建相同的 MD5 哈希,由于它比输入字符串的数据少,那么任何其他哈希系统如何更好?

【问题讨论】:

标签: hash md5 encryption


【解决方案1】:

基本上这是因为 MD5 的输出包含的信息少于输入。这基本上就是哈希算法与加密算法的区别。

这是一个简单的例子:想象一个算法来计算一个 10 位数字的哈希值。该算法是“返回最后 2 位数字”。如果我采用 8023798734 的哈希,我得到 34,但如果你只有 34,你将无法分辨原始数字是什么,因为哈希算法丢弃了 8 位数字的信息。它与 MD5 类似,不同之处在于哈希是通过复杂的过程计算的,而不是仅仅切掉部分数据。

那么,一个哈希值如何比另一个更好呢?一方面,不同的哈希算法可以或多或少地抵抗冲突(当两个输入产生相同的输出时)。冲突的概率与可能的哈希输出的数量成反比。冲突是散列的一个不受欢迎的特性,因为如果您的数据发生变化,您希望散列也发生变化,因此获得更好的散列算法的一种方法是使用具有更多可能输出的散列。在上面的数字示例中,使用最后 4 位而不是最后 2 位将与给定哈希(技术上称为 原像)发生冲突的概率降低到 1 万分之一,而不是 100 分之一,因此,您拥有的任何集合中的所有 10 位数字更有可能具有不同的哈希值。

还有加密安全问题。当您想使用哈希来确保某些数据不被篡改时,希望进行篡改的人无法预测哪些输入会产生给定的输出。如果可以,他们将能够以输出(哈希)保持不变的方式更改输入数据。再次回到数字示例,假设我要通过电子邮件向您发送号码 1879483129,并且此号码原封不动地发送给您,这一点至关重要。我可能会打电话给你,告诉你这个数字的哈希值,即 29,但由于“最后 2 位”算法在密码学上并不安全,一个邪恶的黑客可能会在途中将这个数字更改为 5555555529,而你不会不知道有什么区别。

已经证明MD5 is not cryptographically secure(和SHA-1 is also compromised)。这意味着可以找到对应于任何给定输出的不同输入。它仍然是一种很好的算法来防止随机位翻转等,但如果有人可能想要故意破坏你的数据,你真的应该使用更安全的东西,比如 SHA-256 或更高版本,可能是as part of an HMAC scheme

【讨论】:

    【解决方案2】:

    这是一个简单的答案...

    有有限数量的哈希值,以及无限数量的可哈希明文值。

    因此,反转给定的 MD5 哈希将导致无限数量的可能明文值。

    【讨论】:

    • 从技术上讲,对于某些哈希,可能只有有限数量的不同明文对其进行哈希处理,不是吗?
    • 编辑了我原来的帖子,请阅读底部的新部分。
    • @Sebastian P:不是真的。给定一组(理论上无限)输入,MD5 应该生成一组(理论上无限)输出。 (理论上,给定非 1:1 散列函数和无限数量的输入,任何给定的散列与有限数量的散列对齐是不可能的;这是无限集的含义,而不是 MD5 的含义,即有固定数量的有效 MD5 和,2 ^ 128;给定具有 MD5 和的无限值集,每个哈希有无限数量的冲突)。
    • @ig0774:我想从技术上讲,可以构建一个奇怪的哈希算法,它只将有限的一组输入映射到一个输出。在一个极端的例子中,hash(x) = x<64 ? x : 63 用于非负整数的 6 位哈希x。但就实践中实际使用的散列算法而言,我会非常惊讶地发现一种将有限数量的输入映射到一个输出的算法。 (主要算法可能有数学证明)
    • @David:我猜你对哈希算法的一般看法是正确的(这样的算法可能会满足一些技术需求)。我的观点特别是关于 MD5。
    【解决方案3】:

    这是一个平行的:

    把你家里每个人的年龄加起来。只保留最后两位数。

    现在根据那个数字告诉我每个人的年龄。

    【讨论】:

    • 有人会说它的年龄。
    【解决方案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 的工作原理——比如说维基百科。这不是解释!
    • @KarlRichter 你说得对,我应该提一下:“MD5 是一种类似于 f() 的哈希算法,但要复杂得多。”
    【解决方案5】:

    我只是不明白你是如何使用某种算法将某事物转换为某事物的,并且无法使用反向算法将其转换回来。

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

    转换通过销毁数据来减少存在的数据,并且该数据无法恢复。

    【讨论】:

    • +1 是我见过的最具启发性的类比。嗯...哈希函数和汉堡包。
    • 当然你可以把汉堡变成牛,就像你可以把炒鸡蛋变成鸡肉一样。你给小牛喂汉堡包,然后把它长成一头完整的奶牛。它效率低下,你在这个过程中浪费了很多美味的汉堡包,但它确实有效。
    • @Remus,然后你患上疯牛病的几率微乎其微。 @Rob,土豆变成薯饼会不会那么令人反感?我自己,我也喜欢牛。它们味道很好。为@tangurena +1 进行初步类比!
    • 它没有冒犯性,我只是真的很喜欢奶牛 =[ 不是素食主义者或其他任何东西,你说得对,它们的味道确实很棒。但仍然 =[
    • 和汉堡包一样,哈希值也经常需要加盐。
    【解决方案6】:

    在回答您的问题的第二部分(第一部分的答案已被上述其他人充分给出):MD5 被认为是弱的,因为对密码的攻击证明(即,可以进行的更改在明文中不会导致 MD5 总和发生变化)。其他散列技术可能不太容易受到本质上任意散列冲突的影响(至少这种任意冲突尚未被证明在 SHA-2 散列集等情况下是可能的),因此,攻击者是不太可能复制在非 MD5 技术中散列的散列(理论上,当然,散列冲突攻击可能针对任何散列函数;如果不是这种情况,它作为散列函数将不会成功;问题是攻击者成功“伪造”“正确”明文的难易程度,即散列到相同散列值的明文)。

    顺便说一下,明文的 MD5 和不一定安全,因为它包含“较少”数据或“有损”,但因为它从任意明文计算一个固定范围内的和值(对于明文

    【讨论】:

      【解决方案7】:

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

      虽然确实必须存在多个(甚至无限多)具有相同哈希的消息,但加密哈希的目标是使查找此类冲突变得不可行。

      您可能认为可以通过计算随机消息的哈希值来发现冲突,直到最终两次得到相同的结果。但是,您会低估可能的散列值空间的大小。

      对于 MD5,散列的大小为 128 位。用 Douglas Adams 的话说,128 位空间很大。真的很大。你只是不会相信它是多么巨大令人难以置信的大。可能的哈希数为 2128,或 3.40282367 × 1038。那是 34 后跟 37 个零!如果你能在一秒钟内数到一万亿,那么你仍然需要 100 亿千年才能数完所有 128 位数字。

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

      【讨论】:

      【解决方案8】:

      嗯,不要粗鲁,但在我看来,所有关于“传出的信息比传入的信息少”的答案都没有抓住重点。

      MD5 和类似的加密哈希码的主要用途是加密密码。在那种情况下,我不在乎是否可以重建原始字符串。我只关心我是否可以构造任何哈希到相同值的字符串。

      举一个简化的例子:假设我们的哈希算法是“取最后两位数”。所以如果我的密码是“12345678”,那么哈希码就是“78”。有没有办法从“78”回到“12345678”?不。但如果我破解密码,我不在乎我是否知道你的原始密码是什么。我只是想要一个密码让我进去。所以如果我知道这是算法,我会说很好,我会使用密码“99978”。它的哈希值是“78”,所以密码验证算法会通过它,我就进去了。

      显然 MD5 更难逆转,即使在这种“任何会散列到正确值的东西”的意义上,然后是像“取最后两位数”这样的简单算法。但这真的不可能吗?这也让我很困惑。可以肯定的是,信息在此过程中会被丢弃。但是我不能通过在丢弃信息的任何点填写任何随机值来反转到“任何”值吗?我还没有看过 MD5 的实际算法。我认为这不是一件容易逆转的事情,比如把所有的加号都改成小号或类似的微不足道的东西,或者很久以前有人会这样做。从数以百万计的黑客试图破解这一事实来看,即使理论上可行,也一定非常困难。

      【讨论】:

      • 最初的问题是关于在给定输出的情况下不可能恢复原始输入的算法的存在,而 MD5 绝对有资格作为一种算法。至于您简单地查找将散列到给定输出的 any 输入的想法,如果您想构建一个查找表,这绝对是可能的,但这需要大量的计算能力。我不认为你可以反向运行算法,根据需要填充随机数据,因为 MD5 在每个阶段都会打乱位。 (我以前知道算法但我早就忘记了)
      • 我同意这些答案在技术上是正确的,我只是想指出它们与保护密码的真正问题并不真正相关。把它带到一个荒谬的极端,抛出所有输入数据并将所有内容映射到字符串“foobar”的算法将无法知道原始输入是什么,但它作为密码加密毫无用处算法!
      • 反正我说了,我没看过MD5算法。无论它如何扰乱位,我认为,原则上,您总是可以用恒定零填充任何丢弃的位。不过,我认为该函数的性质使得您不能简单地反转每个步骤。一个说乘以 2 和加 5 的算法可以很容易地通过减去 5 并除以 2 来反转。但是更复杂的操作可能很难像这样逐步反转。总有一天,我将不得不真正研究算法。当我无事可做时。
      • 加密散列函数必须具有几个属性:1) 很容易计算任何给定消息的散列值,2) 找到具有给定散列的消息是不可行的,3) 它是在不改变哈希值的情况下修改消息是不可行的,4)不可能找到两个具有相同哈希值的不同消息。 (来源:en.wikipedia.org/wiki/Cryptographic_hash_function)还有其他的散列函数,它们没有这些属性,因此在密码学中也没有使用。
      • 换句话说,这不是“实际上不可能”(有些人正在尝试),但也不是微不足道的。查看那个维基百科页面,你会发现一些以前使用的加密哈希函数被成功攻击(例如,有办法找到具有相同哈希的另一条消息),因此不再使用。 (寻找“碰撞攻击”和“原像攻击”)。
      【解决方案9】:

      基本上,所涉及的位操作意味着反转它在技术上是不可行的。为了构建一组输出,您将需要疯狂的时间复杂度和巨大的内存复杂度。这根本不是不可能的——但也不是必须的,只是超出了我们最好的超级计算机的能力一英里。

      【讨论】:

        【解决方案10】:

        考虑以下函数: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 并将其与某个哈希值进行比较,如果它们匹配,那么很合理地猜测它来自该密码。

        您可能也有兴趣阅读有关 one-to-one functionsInjective functionscryptographic hash functionsMD5SHA1Don't Hash Secrets from the Benlog Security Blog 的信息。

        【讨论】:

          【解决方案11】:

          另外,由于多个字符串可以创建相同的 MD5 哈希,由于它比输入字符串的数据少,那么任何其他哈希系统如何更好?

          已知一种针对 MD5 的攻击,这使得攻击者可以创建具有 不同 内容但 相同 MD5 哈希的多个文档。这种攻击在计算上是可行的,并且作为演示,被用来“预测”总统选举的结果。 (攻击者在选举前发布了一个哈希值,然后公布了一个包含该哈希值的文档,其中给出了获胜者的名字。但实际上攻击者为每个候选人都有一个文档,所有的哈希值都相同。)

          更好的系统将提供加密保证,即创建两个散列到相同值的不同文档在计算上是难以处理的。 SHA-1 可能就是这样一个系统。

          一个更糟糕的系统会允许攻击,通过给定对任何散列的访问权限,您可以使用该散列创建一个文档。古老的 CRC 系统仍然在许多硬件系统(想想以太网)中使用,很容易受到这种攻击。与 MD5 一样,它是一个散列函数,其中输出不能从输入重构,但给定任何输出,构造具有给定 CRC-32 或 CRC-64 签名的文档是微不足道的。更糟糕的是,您可以将任何您喜欢的文本放在这样的文档中,然后只需在末尾添加垃圾即可获得所需的 CRC。

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

          一个非常好的散列函数将像 CRC 一样快速计算,并且构造两个散列到与 SHA-1 相同值的文档同样困难。不要屏住呼吸...

          【讨论】:

          • 其实CRC-32并没有那么快;在某些系统(例如 ARM)上,某些哈希函数(MD4、Panama...)比 CRC-32 更快。 CRC-32 在硬件中是非常快的,作为一种电路,但是在软件中实现时,必须使用查找表,并且许多 RISC 处理器对查找表相当不适应。
          【解决方案12】:

          大多数答案都没有触及问题的真正重点:散列变换是非线性的,因此非常困难(但并非不可能,只要有足够的计算能力和时间)反转。

          想想对一个数字求平方和求平方根的相对难度。再加上你只有部分信息,所有缺失的位对于产生正确答案都很重要(不像裁剪数字的例子那样)。

          如果你仍然不确定,那么自己尝试逆向 MD5 或任何其他加密哈希函数的步骤 ;-)

          【讨论】:

            【解决方案13】:

            字符串的熵增加,因为在散列过程中丢失了一些信息。这意味着没有足够的信息来重建原始字符串。

            【讨论】:

              猜你喜欢
              • 2010-12-06
              • 2016-10-29
              • 2010-12-01
              • 2011-06-05
              相关资源
              最近更新 更多