【问题标题】:Passwords, salts and auths密码、盐和身份验证
【发布时间】:2011-05-08 05:27:27
【问题描述】:

如果我有一个随机的、16 个字符长的字母数字盐(大小写不同),它是为每个用户生成和存储的,我是否也需要一个站点范围的盐?

也就是说,这样好吗?

sha1($user_salt . $password)

我应该这样做吗?

sha1($user_salt . $password . $site_salt)

还有,

目前,我有一个加密的 cookie,它在数据库中查找会话。在这个会话中,有一个 user_id 和一个 user_token。然后我使用 user_id 查询数据库——如果数据库中 user_id+hash 的 sha1 === user_token,则允许用户通过。

我在每次页面加载时对 user_id 进行第二次查询,这样如果我删除、禁止或更改用户的密码,该操作会立即生效。

这是我通过网站和问题在这里找到的。你怎么看?我错过了什么吗?

我需要添加角色检查,但这可能会添加另一个查询(第三个仅用于身份验证)。有什么建议吗?

【问题讨论】:

    标签: php session authentication passwords salt


    【解决方案1】:

    目前,我有一个加密的 cookie,它在 D B。在本次会议中,有一个 user_id 和 user_token。我那时 使用 user_id 查询数据库——如果 DB中user_id+hash的sha1 === user_token,则允许该用户 通过。

    我对 user_id 进行第二次查询 在每个页面加载时,如果我 删除、禁止或更改密码 用户,该操作立即生效 效果。

    仅在此处没有其他人发现的错误的情况下发表评论:

    1. 你提到 cookie 是加密的
    2. 你的意思是user_id+hash的sha1
    3. 您提到了对密码更改敏感的第二个查询(我不清楚这两个查询是什么)。

    这听起来很像您在 cookie 中存储密码或密码哈希,而不是在 cookie 中存储会话标识符。我建议不要这样做。最大的原因是,像这样使用密码的派生词很有可能将派生词变成密码等价物。

    换句话说,攻击者所需要的只是密码的哈希值,而不是密码本身,以便有效地进行身份验证。这样做的问题是密码的哈希值不会改变,除非密码发生变化(不受您的控制),而会话 ID 会随着您的努力而改变。

    我的建议(如果您希望会话对密码更改敏感)是在密码更改时更改会话 ID。

    【讨论】:

      【解决方案2】:
      sha1($user_salt . $password)
      

      这是非常常见的,但并不好。

      典型的最终用户密码长度约为 8 个字符,并且大多保留 7 位 ASCII 字符集。所以一个典型的密码是大约 64 位或更少的随机数据。现代parallel brute-force attacks 可以通过简单地尝试所有可能的密码来解决这个问题。使用 SHA256 或 SHA512 不会对结果产生重大影响,因为最终用户密码是限制因素。

      根据我在 Stack Overflow 上的阅读,似乎有两种关于密码存储的观点:

      1. 您应该使用computationally expensive approach like BCrypt or scrypt。这样,蛮力攻击变得不可行。这是可行的,但代价是在用户登录时需要服务器提供更多 CPU 能力。请参阅excellent article for an overview of the rationale
      2. 第二种观点是,虽然 BCrypt 和 scrypt 确实可以工作,但它们对于多用户应用程序来说是不可取的,因为它们占用了过多的 CPU 时间——让最终用户等待,或者可能导致拒绝服务攻击通过发送大量的身份验证请求。请参阅lengthy discussion here(请务必同时阅读 cmets)。

      目前,我有一个加密的 cookie,它在数据库中查找会话。在这个会话中,有一个 user_id 和一个 user_token。然后我使用 user_id 查询数据库——如果数据库中 user_id+hash 的 sha1 === user_token,则允许用户通过。

      您没有提到的安全会话处理的一个要点是SSL everywhere to guard against Sidejack。并且用户 ID 通常不利于安全性,因为它们通常是可以猜测的(自动递增的主键)或者它们最终会错误地出现在 URL 等中。不是滚动您自己的会话处理系统,而是您可以使用同行评审的代码库吗?

      【讨论】:

        【解决方案3】:

        使用“站点范围”的盐可能很有用。这意味着不仅您的数据库必须受到破坏,而且您的源代码也必须受到破坏才能真正理解您的密码方案。

        我称之为“盐”和“胡椒”方法。每个用户存储的盐,辣椒是站点范围的值。


        独特的个人盐的目的是使彩虹表无效。 salt 通常存储在数据库中,并附加或附加到密码中。意识到这一点的人仍然可以针对每个用户运行基于字典的攻击,但盐的好处是他们不能使用彩虹表来处理这些常见的字典术语。

        胡椒
        我称之为“胡椒”的目的是为每个密码添加一个可能未知的字符串,这意味着考虑到盐的暴力字典攻击会因为缺少胡椒而完全错过。这也意味着每个字符检查的蛮力需要“发现”更长的密码,这可能需要更长的时间。一旦发现辣椒,这些好处就会消失。

        【讨论】:

          【解决方案4】:

          听起来您正在尝试重新创建 DIGEST-MD5SCRAM。这两种方法都允许您存储您的站点独有的非密码字符串,并与另一方质询/响应以验证他们是否拥有密码字符串,而无需在线发送密码字符串。

          【讨论】:

            【解决方案5】:

            不,您不需要站点范围的盐。盐是用来使彩虹桌无用的。如果您真的想使用站点范围的盐可以,但我认为没有必要。

            我认为,如果您的数据库遭到入侵,并且有人意识到您的密码已用盐进行了哈希处理,他们会转移到下一个安全性较低的站点(当然,除非您正在运行一个值得黑客入侵的站点 - 您很有可能不是:P)

            【讨论】:

              猜你喜欢
              • 2015-12-28
              • 1970-01-01
              • 1970-01-01
              • 2017-06-19
              • 1970-01-01
              • 2020-05-23
              • 1970-01-01
              • 2013-04-07
              • 2016-11-13
              相关资源
              最近更新 更多