两个不同字符串的 MD5 是否有可能相同


Is it possible the MD5 of two different strings be identical?

我正在尝试为我网站的用户创建一个动态头像。类似于堆栈溢出的东西。我有一个PHP脚本,它基于字符串生成图像:

path/to/avatar.php?hash=string

我想使用用户电子邮件的 MD5 作为其头像的名称:(并且由于该字符串 PHP 脚本生成基于的图像)

$email = $_GET['email'];
$hash  = md5($email);
copy("path/to/avatar.php?hash=$hash","path/img/$hash.jpg");

现在我想确定,我可以使用他们电子邮件的MD5作为他们的头像名称吗?我的意思是不是有两个不同的字符串具有相同的 MD5 输出吗?换句话说,我想知道两个不同字符串的输出是否是唯一的?

我不知道我的问题是否清楚..我想知道的是,是否有可能复制两封不同电子邮件的MD5?

由于这里的目标是使用哈希来表示其唯一性而不是加密强度,因此 MD5 是可以接受的。虽然我仍然不推荐它。

如果您决定使用 MD5,请使用您控制的全局唯一 ID,而不是用户提供的电子邮件地址以及盐。

$salt = 'random string';
$hash = md5($salt . $userId);

然而:

  • 碰撞的可能性仍然很小(从2128开始,由于生日悖论,相对较快地接近264)。请记住,这是一个机会,哈希n 和哈希n+1 可能会发生冲突。
  • 没有一种合理的方法可以从哈希中确定 userId(我不考虑索引 128 位哈希,因此您可以查询它们是合理的)。

您以 StackOverflow 为例。

此站点上的用户配置文件如下所示: http://stackoverflow.com/users/2805376/shafizadeh

那么拥有像http://your_site/users/2805376/avatar.png这样的头像网址有什么问题呢?后端存储可以简单地/path/to/images/002/805/376.png

这保证了唯一的名称,并为您提供了一种非常简单易用的方式来存储、定位和反转分配给图像的 ID 返回给用户。

这实际上是 Gravatar 正在做的事情(这是在 Stackoverflow 中获取头像的标准方法)。看看Gravatars的实现。

在实践中,碰撞的可能性可以忽略不计,故意伪造两个(二进制)字符串是很困难的,这会导致相同的MD5和EMail在大小和字符上受到限制。

这种方法的一个问题是Fred-ii提到的,因为MD5的暴力破解速度非常快(每秒100 Giga MD5),有人可以尝试找到原始电子邮件地址,其MD5现在可见。对于简短的电子邮件,这将在合理的时间内起作用。

使用 UUID 可能是从 EMail 地址进行删除的良好替代方法。您可以在没有数据库访问权限的情况下创建此类 ID,并确保不会获得重复项。