PHP 忘记密码功能

2022-08-30 13:00:01

我有一个小型社区网站,我需要实现某种忘记密码的功能。我目前将密码存储在数据库中,使用MD5加密。

是否可以通过电子邮件“解密”并将其发送给用户,或者我需要密码重置页面?


答案 1

MD5 哈希密码不可逆。(MD5是散列,而不是真正的加密,所以有一个微妙的区别)。是的,您肯定希望提供密码“重置”过程(而不仅仅是通过电子邮件发送密码)。

为了给您提供安全密码重置的高级工作流程...

  1. 当用户要求重置密码时,请让他们输入电子邮件地址
  2. 不要指明该电子邮件地址是否有效(只需告诉他们已发送电子邮件)。这是有争议的,因为它降低了可用性(即我不知道我注册了哪封电子邮件),但它为试图收集有关哪些电子邮件的信息的人提供的信息较少。
  3. 生成一个令牌(可能用盐对时间戳进行哈希处理),并将其存储在用户记录的数据库中。
  4. 向用户发送电子邮件,并附上指向 https 重置页面的链接(URL 中的令牌和电子邮件地址)。
  5. 使用令牌和电子邮件地址验证用户。
  6. 让他们选择一个新密码,替换旧密码。
  7. 此外,最好在特定时间范围(通常为 24 小时)后使这些令牌过期。
  8. (可选)记录发生了多少次“忘记”尝试,如果人们请求大量电子邮件,则可以实现更复杂的功能。
  9. (可选)记录(在单独的表中)请求重置的个人的 IP 地址。从该 IP 递增计数。如果它达到,比如说,10...忽略他们未来的请求。

为了给您提供更多有关散列的详细信息...

当您使用PHP中的md5()函数对密码(如密码)进行哈希处理时,无论您在哪个服务器上运行该密码,该密码的最终值都是相同的。(因此,我们可以立即看到散列和加密之间的一个区别......不涉及私钥/公钥)。

所以在这里你会看到人们提到彩虹表的脆弱性。彩虹表的一个非常基本的解释是...你 md5() 对一堆字典单词(弱密码)进行哈希处理,以获得它们的 md5() 哈希值。将它们放在数据库表(彩虹表)中。

现在,如果您破坏了网站的数据库,则可以对彩虹表运行用户的哈希密码,以(实质上)将哈希“反转”回密码。(你并没有真正“逆转”哈希...但你明白了)。

这就是“腌制”密码是最佳做法的地方。这意味着(再次,这里是非常基本的想法)在对用户密码进行哈希处理之前,您将一个随机值附加到用户的密码中。现在,当彩虹表针对您的数据库运行时,它不容易“反转”,因为“password”的md5()哈希与“password384746”不同。

这里有一个很好的SO问答,应该会有所帮助。PHP 密码的安全哈希和盐


答案 2

根据这篇文章 基于表单的网站身份验证的权威指南,用于步骤3。和4.,我不确定您是否应该发送您正在存储的相同令牌。

我想你必须发送令牌,然后对其进行哈希处理并将哈希令牌存储在数据库中。否则,如果您的数据库遭到入侵,则可以访问重置密码页。

总结一下:

$token = md5(microtime (TRUE)*100000);
$tokenToSendInMail = $token;
$tokenToStoreInDB = hash($token);

其中哈希是一种哈希算法。


推荐