在PHPass中使用现有MD5散列是否存在安全隐患?



在我知道这一点之前,我实现了一个使用md5作为散列算法的登录系统。现在我知道了更多,我想转移到使用PHPass。我的问题是,系统已经在生产中,要求所有用户更改密码将是最令人头疼的事情。

我想出了一个足够简单的解决方案,但鉴于我之前的错误,我想确保我不会因为无知而犯同样严重的错误。

我的解决方案如下:

改变
  1. md5($_POST['pass'])
  2. 检查md5哈希密码是否符合数据库值

  1. md5($_POST['pass'])
  2. 传递md5哈希密码给$hasher->HashPassword()
  3. 使用$hasher->CheckPassword()根据DB
  4. 中的值检查重新散列的密码

为了清楚起见,我只是重新散列md5版本,因为这是我已经在DB中拥有的。它不打算作为一个额外的安全措施(尽管如果是,那很好!)。

  1. MD5()问题在这个狂热的程序员社区网站上被夸大了。这个散列算法实际上并没有什么不好,特别是与通常的新手应用程序的其他部分相比。在普通的PHP站点上使用phpass技术就像在草屋的纸门上使用安全锁。

  2. 保持密码安全的最重要的事情是防止虚拟被窃取并用于其他网站上的同一用户(哦,我的!)是密码强度和盐。不是哈希算法本身。没有哈希技术会保护像"1234"或"joe"这样愚蠢的传递。
    因此,md5 + strong password + average salt优于usual password + phpass

  3. 没有一个单一的原因phpass现有的md5哈希
    一个合理的迁移算法是

    • 检查此用户记录是否有新的散列标志。
    • 如果设置为-
      • 设置phpass认证
    • 如果没有:
      • md5 ($ _POST['通过'])
      • 检查md5哈希密码是否符合数据库值
      • 如果正确的:
        • phpass ($ _POST['通过'])
        • 在数据库中保存结果
        • 为该记录设置新的散列标志

您所谈论的问题并不是PHPass所特有的,而是一般的散列密码。基本上就是双重哈希。这个话题已经在另一个问题中讨论过了:是"双哈希"吗?一个比散列一次更不安全的密码?

如果你看一下那里,你可以看到仍然存在关于双哈希是否更糟糕的争论,因为它减少了传递给第二个(或后续)哈希函数的字符范围。然而,它减慢了哈希过程,打击暴力攻击,但只做两次不会起到那么大的减速带作用。

如果你不想处理双哈希,你可以尝试做的是在你的users数据库表中添加一个标志字段,并为所有在你设置新的PHPass哈希形式后加入的新用户设置为true。然后,当用户登录时,如果他们没有设置标志字段,则使用旧的散列系统,或者您在问题中详细说明的修改版本。如果它们确实有标记字段,你可以使用你设置的任何新的哈希过程。

Update:实际上,在此基础上,您可以尝试使用该标志设置,一旦他们在旧系统下登录,如果它是匹配的,那么您仍然会在$_POST数据中拥有他们未散列的密码,因此您可以通过新的散列设置运行该设置,保存新散列,然后将标志设置为true,因为它们已升级到新的散列方法。从那时起,他们将使用新的哈希方法。

你在这里得到了一些非常可疑的建议,所以你可能想问一下IT安全。与一些人所说的相反,密码哈希算法确实很重要;您希望使用salt和慢散列(如bcrypt、script或PBKDF2)。请参阅:我应该使用哪种密码散列方法?有安全专家推荐用比特币存储密码吗?如何安全地散列密码?最安全的密码哈希算法?PHPass是一个很好的库。

要将用户迁移到PHPass,您需要有两个密码哈希数据库:旧的(使用MD5哈希)和新的(使用PHPass哈希)。最初,这个新文件将是空的。当用户登录时,检查在旧密码哈希数据库(使用MD5哈希)中是否有针对他们的条目,如果在那里没有找到条目,则查看新密码哈希数据库(使用PHPass哈希)。如果在旧数据库中找到一个条目,则需要使用MD5来散列并检查其密码。如果正确,则需要使用PHPass对其明文密码进行散列,将其插入新密码散列数据库,并从旧密码散列数据库中删除它们。如果在旧数据库中没有找到条目,可以在新数据库中检查条目,并使用PHPass检查其密码的有效性。基本上,您可以在每个用户下一次登录时逐渐将其从旧式散列迁移到新式散列。这有道理吗?

我的方法确保密码长度至少为8个字符,并且包含非随机垃圾字符("垃圾"意味着可能不可打印/空字符):

function pass_hash ($password) {
    # take first 8 characters of the raw md5 hash
    $hashslice = substr(md5($password, true), 0, 8);
    # add it to the password and hash again
    return md5($password . $hashslice);
}

如果你不喜欢md5,就用sha1,原理是一样的。

相关内容

最新更新