在 MD5 产生碰撞之前有多少随机元素?

Posted

技术标签:

【中文标题】在 MD5 产生碰撞之前有多少随机元素?【英文标题】:How many random elements before MD5 produces collisions? 【发布时间】:2010-09-17 03:11:43 【问题描述】:

我在 Amazon S3 上有一个图像库。对于每张图片,我会 md5 我服务器上的源 URL 加上时间戳以获得唯一的文件名。由于 S3 不能有子目录,我需要将所有这些图像存储在一个平面文件夹中。

我需要担心生成的 MD5 哈希值的冲突吗?

奖励:在我开始看到 MD5 产生的哈希值冲突之前,我可以拥有多少个文件?

【问题讨论】:

相关:Are there two known strings which have the same MD5 hash value? 字面意思是 second 文件可以具有与第一个相同的 MD5。然而,可能性非常小。 【参考方案1】:

等等,是吗:

md5(filename) + timestamp

或:

md5(filename + timestamp)

如果是前者,你最容易获得 GUID,我不会担心。 如果是后者,请参阅 Karg 的帖子,了解您最终将如何遇到碰撞。

【讨论】:

请详细说明包含时间戳如何增加碰撞的机会 @BradThomas:它没有。无论是文件名还是文件名+时间戳的组合,MD5的碰撞风险都是一样的。但在第一种情况下,您需要同时发生 MD5 冲突和时间戳冲突。 这仍然留下每分钟与两个用户发生冲突的 2^(128^60) 机会。字面上无法使用。 @BradThomas 更清楚一点:md5(filename) + timestamp 大大降低了碰撞风险,因为您需要对完全相同的时间戳进行 md5 碰撞才能产生整体碰撞。 md5(filename + timestamp)md5(filename) 相同,假设文件名一开始是随机的(因为向随机内容添加更多随机性只会改变单个 md5 结果,并且生日问题仍然存在于所有 md5 哈希中)。【参考方案2】:

S3 可以有子目录。只需在键名中添加一个“/”,您就可以访问这些文件,就好像它们位于不同的目录中一样。我使用它根据 S3 中的用户 ID 将用户文件存储在单独的文件夹中。

例如:“mybucket/users/1234/somefile.jpg”。它与文件系统中的目录并不完全相同,但 S3 API 有一些特性使其工作方式几乎相同。我可以要求它列出所有以“users/1234/”开头的文件,它会显示该“目录”中的所有文件。

【讨论】:

这应该是我认为的内容,因为它实际上并没有回答有关碰撞可能性的问题【参考方案3】:

MD5 冲突极不可能发生。如果你有 9 万亿 个 MD5,那么 9 万亿 中只有一次机会会发生碰撞。

【讨论】:

许多其他答案都谈到了添加 一个 项时发生冲突的概率。我认为我的答案更有用,因为它谈到了整个表的可能性。 这与MD5无关,不正确。这就像说,如果你有 9 万亿只猫,那么其他人有 9 万亿只猫的几率是 1 分之一。这里的关键问题是您可以获得具有多个值的相同哈希。 @JoonasAlhonen - 是的,这是真的。很多穷人以此为借口再买一张他们买不起的彩票。【参考方案4】:

两个散列意外碰撞的概率是 1/2128 which is 1 in 340 undecillion 282 decilion 366 nonillion 920 octillion 938 septillion 463 sextillion 463 quintillion 374 千万亿607万亿 4310亿 7.68亿 21.1万 456.

但是,如果您保留所有哈希值,那么由于birthday paradox,概率会更高一些。要使任何散列与任何其他散列冲突的概率为 50%,您需要 264 个散列。这意味着要发生冲突,平均而言,您需要散列 6 billion files per second for 100 years。

【讨论】:

“碰撞概率为 1/2^64” - 什么?碰撞的概率取决于已经散列的项目数量,它不是一个固定的数字。事实上,它正好等于1 - sPn/s^n,其中s 是搜索空间的大小(在本例中为2^128),n 是散列的项目数。您可能想到的是2^64,这是您需要进行 MD5 哈希才能有 50% 的碰撞几率的近似项目数。 +1 因为我一直想知道如何计算超过 999 万亿,哈哈(哦,是的,你的回答很有用) 很遗憾,您仍然不正确。您假设哈希函数是真正随机的。它不是。这意味着碰撞概率更高。 JørgenFogh:所有物理定律也“不正确”。这种程度的迂腐是不必要的,因为它不会以任何有意义的方式改变答案。 所以你说有机会!【参考方案5】:

虽然随机 MD5 冲突极为罕见,但如果您的用户可以提供文件(将逐字存储),那么他们可以设计发生冲突。也就是说,他们可以故意创建两个 MD5sum 相同但数据不同的文件。确保您的应用程序能够以合理的方式处理这种情况,或者可能使用更强的哈希值,例如 SHA-256。

【讨论】:

使用盐可以解决用户工程问题,不是吗? 这取决于盐的应用方式。它需要是用户提供的数据的前缀,或者更好的是 HMAC 的密钥。不过,练习深度防守可能仍然是个好主意。 请注意,虽然 SHA256 的长度为 256 位,但您可以通过将 SHA256 截断为更少的位来权衡与存储的密钥长度发生冲突的风险,例如使用 SHA256 但将其截断为 128 位(这比使用 MD5 更安全,即使它们具有相同的位数)。【参考方案6】:

冲突的粗略经验法则是取值范围的平方根。您的 MD5 信号大概是 128 位长,因此您可能会看到超过 2^64 图像的冲突。

【讨论】:

您的意思可能是 128 位,而不是 2^128。 :-) en.wikipedia.org/wiki/Birthday_Problem 有关该问题的更多信息。【参考方案7】:

虽然 MD5 由于冲突而广为人知,但随机数据之间的意外冲突是exceedingly rare。另一方面,如果您对文件名进行哈希处理,那不是随机数据,我预计会很快发生冲突。

【讨论】:

我对 taylors 示例的唯一问题是,如果有人获得了您数据库的副本,他们可能会使用彩虹表找出信用卡号... 虽然我不会选择将 MD5 用于信用卡,但彩虹表包含 10,000,000(8 位是我见过的最小长度信用卡)和 9,999,999,999,999,999(最大)之间的所有有效信用卡号16位数字)仍然是一个要生成的大表。窃取这些号码可能有更简单的方法。【参考方案8】:

可能性有多大并不重要;有可能的。它可能发生在您散列的前两件事上(非常不可能,但可能),因此您需要从一开始就支持冲突。

【讨论】:

当然还有很多其他不好的事情发生的概率为 1/2^128。您可能不想单独担心这个问题。 这里可能发生的最糟糕的事情是你可以得到一张照片。对于相对较少的数字,我不会担心。现在,如果您的软件正在控制自动驾驶仪降落飞机,那就是另一回事了。 你不能是认真的。您需要每秒对 60 亿个文件进行散列处理,持续 100 年才能获得很好的碰撞机会。即使你非常非常倒霉,它也可能需要超过整个 S3 容量的使用时间超过人类的一生。 您的数据库及其备份全部失败的可能性要高出数十亿倍。碰撞不值得担心。 利用碰撞预防时间建造一个掩体来放置你的服务器!那些讨厌的流星可能会击中你(非常不可能,但有可能),所以你需要支持流星庇护所免受乞讨。

以上是关于在 MD5 产生碰撞之前有多少随机元素?的主要内容,如果未能解决你的问题,请参考以下文章

shell系列生成随机数的方法

shell系列生成随机数的方法

产生10个随机数5-9之间 统计一个int类型的一维数组中有多少个在[min,max]之间的数

生成随机数

C语言 统计数组每个元素个数

MD5加密会产生16位跟32位的结果?