【问题标题】:Php, is password reset token without database secure?Php,没有数据库的密码重置令牌是否安全?
【发布时间】:2013-09-18 15:45:02
【问题描述】:

我正在为网站制定密码重置程序。正确的实现建议在数据库中存储一个随机加盐令牌哈希和到期日期。

但我遇到了一个不在数据库中存储令牌的解决方案: https://stackoverflow.com/a/3165086/980737

我正在考虑使用上述方法,但使用 PASSWORD_BCRYPT 将 sha1() 替换为 password_hash()。

对我来说看起来不错,但我不是安全专家。上面没有数据库选项安全吗?如果不是为什么?

【问题讨论】:

  • 您链接的答案在解释所使用的概念方面做得不好。由于使用了所有这些无法解释的值,我有一种不好的感觉。例如,当用户因为忘记密码而想要重置密码时,将用户密码放入进程中,这有点违背了目的......
  • 对不起,但你给我们的链接是一个不好的例子(解释)
  • @Sven 它是当前的hashed 密码(然后用附加信息再次散列)用作“假定的”服务器机密。不过评论的第一句话很到位:这是一个没有很好解释的可怕示例/链接。

标签: php security passwords bcrypt


【解决方案1】:

我认为链接的方法是“不安全”

代码使用手动方法来尝试验证 URL/令牌数据的完整性。这个想法是只有服务器(应该是唯一知道用户密码和盐的实体)可以生成给定的 SHA1;收到 URL 后,可以重新生成 SHA1,如果匹配,则解决方案建议 URL“必须”是服务器生成的,因此可以信任。

但是,上面的假设可能会被违反! 如果 bcrypted/hashed 密码已知1,那么攻击者可以生成任意重置 URL 并获得访问权限。这是因为攻击者拥有伪造他自己的“可验证”URL 所需的所有信息。

应用加密 - 在生成令牌之后,以避免像 Blender 指出的那样暴露信息 - 或者使用 HMAC 会增加所需的知识,因为使用额外的“服务器机密”来生成此类重置 URL。加密 MAC 验证用于对客户端存储和返回的数据进行机密性和完整性检查2

但是,如果攻击者获知了这个额外的“服务器机密”,那么上述相同的问题仍然存在,并且可以随意生成虚假的重置 URL。 (但在这一点上,我怀疑还有其他更紧迫的安全漏洞..)


就 bcrypt 与 SHA1 而言:由于 巨大的 输入空间,没有必要切换 - 此时密码应该已经被散列了! - 以及重置请求的有限超时。因此,在此处切换到 bcrypt 不会增加额外的安全性,使用 bcrypt 并不能缓解前面提到的问题。 (另一方面,SHA1 对于实际的散列密码来说是一个糟糕的选择!)


1 虽然帐户/密码信息从不泄露会很好,但密码散列的关键在于防止在发生此类泄露时[大规模] 被利用。由于此类泄漏因此被视为“可能发生”的情况(并且它们确实发生),因此额外的安全措施应该已经假定此类帐户/密码信息可能不会用作安全机密。

2ASP.NET ViewState secuity/validation 支持加密和完整性验证,这表明,通过可靠的实施和安全预防措施,无数据库/存储的方法可以在安全的企业中工作环境。

【讨论】:

    【解决方案2】:

    随机标记应该是真正随机的。通过使令牌成为非随机数据的函数,您会泄露敏感信息。

    如果您想自己实现,请生成一个安全的随机令牌:

    $token = hex(openssl_random_pseudo_bytes(10, true));
    

    并使其在 20 分钟或一个小时内过期。

    【讨论】:

      猜你喜欢
      • 2020-05-29
      • 1970-01-01
      • 2023-04-10
      • 1970-01-01
      • 2019-05-02
      • 2017-11-05
      • 2020-07-12
      • 2012-05-21
      • 2013-04-02
      相关资源
      最近更新 更多