2

在我开始之前,我知道 MD5 已被破坏(碰撞攻击和散列速度)并且不应该用于散列密码,但只是为了它,请耐心等待。

我的问题是:使用 md5 散列时的盐位置如何影响散列的“质量”或“强度”?

假设我有以下代码,它使用他的电子邮件地址的一部分作为盐来散列用户密码:

<?php
    $email = 'user@emailservice.ex';
    $password = 'RandomPassWithChars';

    $segments = explode('@', $email);
    list($saltPart1, $saltPart2, $saltPart3) = $segments;

    $hash = md5($saltPart1.$password.$saltPart3.$saltPart2);
?>

该代码是否会减慢蛮力/字典/彩虹表攻击,而不是说:

<?php
    $password = 'RandomPass';
    $salt     = 'RandomSaltStoredInTheDatabase';
    $hash = md5($password, $salt);
?>

是否值得尝试像在第一个代码中那样对密码进行加盐,或者它会产生与第二个代码相同的结果?有什么好处吗?第一个代码是否比第二种方式延迟破解以这种方式散列的密码列表?

这就引出了第二个问题:将盐存储在数据库中是否比从用户 ID(例如电子邮件地址)获取盐安全?在我看来,一旦攻击者获得了数据库的副本,该副本也包含盐,它使他的生活更容易尝试破解哈希。但是如果不存储盐,攻击者还需要创建盐的算法。如果我错了,请纠正我。

我希望我说清楚了。感谢您提前提供任何答案。

4

3 回答 3

8

第一个问题:

盐的位置对特定哈希的安全性没有影响。一个好的散列函数具有完美的熵,因为对于每个变化的输入位,每个输出位都有 50% 的机会发生变化。

特定顺序的任何可能的安全优势将完全来自用于将盐与预期密码连接起来的算法的相对缓慢(例如,如果"password" . "salt"比 慢"salt" . "password",则使用前者)。但是,大多数编程语言都没有那种性能“问题”。

第二个问题:

如果盐明确存储在数据库中,攻击者将知道盐,并能够发起暴力散列攻击。如果盐是未知的,仍然可以使用蛮力密码攻击(尽管通过在尝试之间插入延迟很容易使这种攻击无效)。此外,攻击者可能能够对程序进行逆向工程并检索哈希字段。

至于哈希的安全性,如果用户在两个不同的地方拥有相同的电子邮件和密码,这否定了随机盐的好处之一,即相同的哈希在两个地方都可见。

就个人而言,我认为散列的最佳方法是使用:

"password" . "salt" . "internalconstantvalue"

这样做的好处是简单,并且不亚于大多数其他安全方法。

于 2012-06-20T12:34:27.877 回答
1

这取决于攻击者是试图绕过您的安全还是试图找到密码。

如果由于散列算法的加密弱点,攻击者依赖于查找与数据库的给定散列的冲突,则盐不会产生任何影响:我有一堆位,我想找到一些输入到XXX 哈希算法,它在输出中给了我相同的位。

如果他试图通过尝试每种可能的组合来强制密码,那么他可以收集的关于原始密码的任何信息都会有所帮助:

  • 长度
  • 组成(字母数字字符,特殊符号,...)
  • ...

通过创建自己的 salt 算法,您实际上是在尝试通过混淆来确保安全,这确实会限制任何不知道您的算法的人对密码进行暴力破解,但它不会增强散列算法。

于 2012-06-20T12:30:46.703 回答
0

当你处理密码安全时,总是假设如果攻击者可以访问你的数据库,那么他就可以访问你的代码。

因此,当涉及到加盐时,只需生成一个随机值的散列(例如mcirotime()),并在散列之前使用它对密码进行加盐,并将其存储在数据库中密码旁边的列中。

在将哈希添加到密码中时,我个人的看法是,将其放在首位或放在最后还是放在中间并不重要。

你想要安全吗?然后使用慢速散列算法,我强烈推荐PHPass,因为它使用bcrypt(基于 Blowfish)作为默认散列算法。

于 2012-06-20T12:28:42.133 回答