12

我正在阅读这个关于 MD5 哈希值的问题,而接受的答案让我感到困惑。据我了解,加密哈希函数的主要属性之一是不可能找到两个具有相同哈希值的不同消息(输入)。

然而,对于为什么 MD5 哈希值不可逆?因为无限数量的输入字符串会产生相同的输出。 这对我来说似乎完全矛盾。

此外,让我有些困惑的是算法是公开的,但哈希值仍然是不可逆的。这是因为哈希函数中总是存在数据丢失,因此无法判断哪些数据被丢弃了吗?

当输入数据大小小于固定输出数据大小时会发生什么(例如,散列密码“abc”)?

编辑:

好的,让我看看我是否直截了当:

  1. 从哈希中推断输入真的非常困难,因为有无限数量的输入字符串会生成相同的输出(不可逆属性)。
  2. 然而,即使是找到生成相同输出的多个输入字符串的单个实例也非常非常困难(抗碰撞特性)。
4

6 回答 6

19

警告:长答案

我认为所有这些答案都缺少加密哈希函数的一个非常重要的属性:不仅不可能计算经过哈希处理以获得给定哈希的原始消息,而且不可能计算任何将哈希到给定哈希值的消息. 这称为原像电阻

(通过“不可能” - 我的意思是没有人知道如何在比猜测每条可能的消息所花费的时间更短的时间内完成它,直到你猜到被散列到你的哈希中的那个。)

(尽管人们普遍认为 MD5 不安全,但 MD5 仍然具有抗原像性。任何不相信我的人都可以随意给我任何散列的2aaddf751bff2121cc51dc709e866f19东西。MD5 没有的是抗碰撞性,这完全是另外一回事。)

现在,如果你不能在加密哈希函数中“向后工作”的唯一原因是因为哈希函数丢弃数据来创建哈希,那么它不能保证原像抗性:你仍然可以“向后工作”,只需插入散列函数丢弃数据的任何地方的随机数据,虽然你不会想出原始消息,但你仍然会想出一个散列到所需散列值的消息。但你不能。

所以问题变成了:为什么不呢?(或者,换句话说,你如何使函数原像抗性?)

答案是密码散列函数模拟混沌系统。他们接收你的信息,将其分解成块,混合这些块,让一些块相互交互,混合这些块,然后重复很多次(好吧,一个加密哈希函数可以做到这一点;其他人有他们的自己的方法)。由于块相互交互,块 C 不仅必须与块 D 交互以生成块 A,而且还必须与块 E 交互以生成块 B。现在,当然,您可以找到块 C、D 的值, E 会在你的哈希值中产生块 A 和 B,但是当你再往前走时,突然你需要一个块 F 与 C 交互以生成 D,并与 E 交互以生成 B,并且没有这样的块可以同时做到同时!您一定猜错了 C、D 和 E 的值。

虽然并非所有加密散列函数都与上面描述的块交互完全一样,但它们有相同的想法:如果你试图“向后工作”,你最终会遇到很多死胡同,而且时间您尝试足够的值来生成原像大约需要数亿年到数百万年(取决于散列函数),这并不比尝试消息直到找到有效消息所花费的时间好多少。

于 2009-06-26T02:44:06.513 回答
13

1:散列的主要目的是将一个非常非常大的空间映射到一个更小但仍然非常大的空间(例如,MD5,它将获取“任何东西”并将其转换为大小为 2^128 的空间 - 大,但没有 aleph-0 大。)

除了其他特性之外,好的散列可以均匀地填充目标空间。错误的散列以块状方式填充空间,为许多常见输入提供相同的散列。

想象一下愚蠢的哈希函数 sum(),它只是将输入数字的所有数字相加:它成功向下映射,但是在低位有一堆冲突(输入具有相同的输出,如 3 和 12 和 21)输出空间的末端和空间的上端几乎是空的。因此,它对空间的利用非常差,容易开裂等。

因此,即使使用目标空间的良好哈希将很难找到具有相同输出的两个输入,仅凭几率:如果 MD5 是完美的,两个输入具有相同输出的几率将是 2^- 128. 这是相当不错的几率:在不诉诸更大输出空间的情况下,您可以做到最好。(事实上​​ MD5 并不完美,这是使其易受攻击的原因之一。)

但是,大量的输入将映射到任何给定的哈希仍然是正确的,因为输入空间是“无限的”,并且将无穷大除以 2^128 仍然可以得到无穷大。

2:是的,哈希总是会导致数据丢失,除非您的输出空间与您的输入空间相同或大于输入空间 - 在这种情况下您可能不需要哈希!

3:对于较小的输入,最佳做法是对输入进行加盐。实际上,这对于任何加密散列都是一个很好的做法,因为否则攻击者可以向您提供特定的输入并试图找出您正在使用的散列。'Salt' 只是您在输入中附加(或前置)的一组附加信息;然后你散列结果。

编辑:在密码学中,哈希函数能够抵抗原像攻击也很重要,直观地说,即使知道许多其他输入/输出对,也很难猜测给定输出的输入。“sum”函数可能很容易被猜到(但由于它破坏数据仍然可能不容易反转)。

于 2009-06-24T13:39:00.477 回答
7

您可能会感到困惑,因为您引用的问题的答案 令人困惑。加密散列函数的要求之一是它应该是抗原像的。也就是说,如果您知道 MD5(x) 但不知道消息 x,那么很难找到任何 x'(等于 x 或不同于 x)使得 MD5(x') = MD5(x)。

抗原像性与可逆性不同。如果给定 y = f(x),则函数是可逆的,恰好有一个 x 适合(无论这是否容易)。例如定义 f(x) = x mod 10。那么 f 是不可逆的。从 f(x) = 7 您无法确定 x 是 17、27 还是其他值。但是 f 不是抗原像性的,因为 f(x) = 7 的值 x' 很容易找到。x' = 17、27、12341237 等都有效。

在进行加密时,您通常需要具有抗原像性(以及其他属性,例如抗碰撞性)的功能,而不仅仅是不可逆的功能。

于 2009-06-26T07:59:05.720 回答
2

这些是哈希函数的一般属性。

不过请注意,MD5 不应再使用,因为其中已发现漏洞。检查“漏洞”部分和详细说明这些攻击的外部链接。 http://en.wikipedia.org/wiki/Md5 您可以通过仅更改消息中的 128 位来进行 MD5 冲突。

SHA-1 对于简单的散列是安全的,尽管有一些攻击会使它对资金充足的实体(政府、大公司)变得更弱

SHA-256 是未来几十年对抗技术的安全起点。

于 2009-06-25T19:20:40.900 回答
1

然而,对于“为什么 MD5 哈希值不可逆?”这个问题的共识答案。是因为“无限数量的输入字符串将产生相同的输出。”

对于任何散列函数都是如此,但它不是密码散列函数的本质。

对于诸如密码之类的短输入字符串,理论上可以反转加密哈希函数,但它在计算上应该是不可行的。即你的计算运行时间太长而无用。

这种不可行的原因是输入在哈希值中是如此彻底地“混合在一起”,以至于不可能用比计算所有输入的哈希值的蛮力攻击更少的努力来解开它

于 2009-06-24T13:39:21.990 回答
1

“为什么 MD5 哈希值不可逆?” 是因为“无限数量的输入字符串>将产生相同的输出”

这就是不可能反转散列函数(获得相同的输入)的原因。加密哈希函数是抗冲突的,这意味着也很难找到映射到相同输出的另一个输入值(如果您的哈希函数是 mod 2 : 134 mod 2 = 0;现在您无法从结果,但我们仍然可以找到具有相同输出值的数字 2(134 和 2 碰撞))。

当输入小于块大小时,填充用于使其适合块大小。

于 2009-06-24T13:42:02.577 回答