如何安全存储哈希?

时间:2014-03-24 23:33:20

标签: php security encryption hash cryptography

当用户想要重置密码时,会发送一封带有唯一网址的电子邮件,以便重置密码。像这样: website.com/forgot.php?email” $电子邮件。 '&安培;散列=' $ thehash

$ thehash是存储在数据库中的每个用户的唯一哈希。

问题是$ thehash就像它在URL中使用的那样存储在数据库中。这就像用纯文本存储密码一样愚蠢。如果有人可以访问数据库,那么我将密码与sha512和安全盐一起存储并不重要,攻击者可以使用数据库中的所有值(电子邮件和哈希)访问所有帐户,更改用户的密码。

当我对用户密码进行哈希处理时,用户只能获得数据库中无法找到的信息的一部分,因此明文密码就可以解决了。但现在,我不知道该怎么做,因为我没有在数据库中找不到任何独特的东西。那么解决这个问题的好方法是什么?如何安全存储哈希值?

6 个答案:

答案 0 :(得分:5)

问题不在于您如何存储哈希值,而是与重置链接的工作方式有关。

由于您提到的原因,您不想使用哈希来验证用户的密码重置。

请改用易腐令牌。每当用户请求重置密码时,生成一个令牌(256位应该足够)并将其哈希值与请求它的用户以及令牌创建日期时间一起存储在您的数据库中。将该令牌放入重置链接(而不是电子邮件+哈希)。当用户点击该链接时,您的服务器将收到该令牌,找到相应的用户,并且可以安全地更改密码。

只将令牌的哈希存储在您的数据库中,但在电子邮件链接中使用未哈希的令牌,您确保即使攻击者仍然可以访问您的数据库,他也会赢得&#39 ; t能够伪造自己的重置链接。

通过将用户点击链接的时间与生成令牌时存储的日期时间进行比较,您可以控制重置链接的有效时间(并避免用户忘记删除链接的情况)电子邮件,让他的电子邮件帐户遭到入侵,并让攻击者使用重置链接。)

检查此Authlogic Password Reset Tutorial是否完整实施。

答案 1 :(得分:1)

  

当用户想要重设密码时......

我将推荐你OWASP Forgot Password Cheat Sheet,其实质上是:

1收集身份数据或安全问题

2验证安全问题

另一种为用户提供一些东西的替代方法:

3通过侧通道发送令牌:“在第2步之后,立即锁定用户的帐户。然后通过电子邮件或短信向用户发送具有8个或更多字符的随机生成的代码......这也是一个好主意使你的系统生成的随机代码只有有限的有效期,比如不超过20分钟......当然,一旦用户的密码被重置,随机生成的令牌应该没有更长的有效......“

  • 请允许我在此添加您可以通过电子邮件向用户发送原始令牌,但使用与普通密码完全相同的保护(即PBKDF2 / BCrypt / SCrypt)存储它的哈希值,并存储只有数据库中的结果哈希。然后,当用户使用密码重置电子邮件时,如果它仍然在非常短的时间窗口内,请接受他们给你的任何内容,并使用password_verify()函数将其与重置令牌哈希进行比较。

    4允许用户更改密码

因此,您的重置令牌受以下保护:

  • 仅根据经过验证的请求发出
  • 仅在几分钟内有效
    • 即。希望对于窃取数据库备份的人来说,使用它们的时间太短了!
  • 可选择通过密码散列机制保护其免受恶意数据库访问,就像任何其他密码一样。

当令牌处于活动状态时,您的重置令牌显然不会受到访问用户电子邮件帐户的攻击者的保护,或者可以更改列出的电子邮件帐户的攻击者。

通过整个安全问题重置密码显然不会受到知道或可能危及安全答案且有权访问(或可以更改)用户列出的电子邮件帐户的攻击者的保护。

答案 2 :(得分:0)

@relentless是正确的。如果被攻击者获得对数据库的访问权限,他/她是否能够重置密码,无论他们是否拥有密钥?您还假设他们已获得对用户电子邮件帐户的访问权限或完全猜到了哈希值。另外需要考虑的是,您不必将哈希值存储在数据库中。考虑一下:让我们说哈希是通过将用户的电子邮件与您之前确定的密钥相结合来创建的。当重置页面加载时,只需重新散列电子邮件和密钥,看它是否与查询字符串中的散列匹配。

答案 3 :(得分:0)

互联网上有关于此问题的多篇帖子,但我的看法如下。

如果我在以下内容中出错,请纠正我......

如果您的实际数据库和登录凭据已知/受到损害,数据可以更改,则黑客只能造成永久性损害。否则,即使更改URL中的电子邮件地址,数据仍然是安全的。只要您不给潜在的黑客提供更改电子邮件地址的后门;这本身就是黄金。

如果使用 单向不可逆 哈希方法正确存储密码,那么它们就是这样; 不可逆转 并且很有可能它们无法重新组合在一起。如果用户的密码遭到入侵,那么这将是一个红旗,您可以重新思考您使用数据库的方式。

充其量,即使用户的密码发生了变化,也要为用户提供一种方法来重新更改密码,然后设置一列来跟踪其更改次数。如果它经常变化,那么再次另一个红旗。我已经使用了类似于您现在使用的方法,即使在更改URL中的电子邮件地址时,DB中也没有任何更改;一切都必须匹配。

另外,即使有人确实更改了用户的密码,但根据您为用户提供的权限或访问权限,黑客将要执行的操作,请再次更改密码?

网址应包含与帐户关联的电子邮件,存储在数据库中然后检索的散列密钥,并且只有在黑客掌握了用户的电子邮件帐户凭据且已获得访问权限的情况下才能使用什么应该是一个独特的链接。

我不知道您目前正在使用哪种哈希方法,但有很多建议使用这种方法。

其他链接:


<强>脚注:

如果我可以:(我同意的话)引用owlstead

&#34;最好的方法是PBKDF,如PBKDF2,bcrypt和scrypt。如果可能,不应使用crypt,password_hash()是crypt和bcrypt的实现,而不是单独的算法。如果选择密码错误,用户密码可能会受到损害。密码哈希或PBKDF的一种方法无法逆转,但它们可能是强制性的(例如使用字典攻击)&#34;

答案 4 :(得分:0)

为什么不将$ thehash作为会话变量传递,然后检查它指向的函数&#39;如果已设置?&#39;如果是,则执行,之后执行删除会话变量。

答案 5 :(得分:0)

  

如何安全存储哈希?

     

...

     

那么解决这个问题的好方法是什么?如何安全存储哈希值?

这是&#34;无人值守密钥存储&#34;问题,没有解决方案的问题。见Peter Gutmann Engineering Security

OWASP的John Steven提供了与密码散列和存储相关的更好的写作之一。他带您了解各种威胁并解释为什么事情以某种方式完成。参见