如何以安全的方式提供密码重置功能?

时间:2013-08-20 01:38:51

标签: php security passwords

我目前正在建立一个网站,用户需要创建一个个人帐户才能玩同一个网站上的游戏。我目前难以搞清楚的是如何在忘记密码的情况下为用户实现安全密码重置功能。

这是目前的流程:

第1步:用户点击网站上的“忘记密码”链接 第2步:在发送电子邮件之前,用户将被带到表格并输入两次电子邮件地址 第3步:电子邮件包含指向其他表单的链接,用户可以在此处输入两次新密码进行确认。输入第二个表单后,系统会在数据库中的Recover_Password表中插入一条新记录,该表包含“id”,“token”,“created_at”和“expires_at”列。

这是链接 - > (mywebsitename)的.com /格式ID = 99999&安培;标记=
其中“id”是用户的ID,“{”是从do_hash($id . date('Y-m-d'))生成的

第4步:用户填写表单并进入登录页面。系统从数据库中清除令牌记录,并从用户表中更新用户的当前密码。

此外,我想知道如果用户在第二种形式时尝试刷新浏览器页面该怎么办。我目前只允许访问页面,如果get参数中有id和token值,并且它们都存在于数据库中。

我在整个网站上使用Codeigniter,如果这是一种安全的方式,我需要知道,以及我应该如何处理令牌和数据库。谢谢!!

1 个答案:

答案 0 :(得分:8)

处理密码重置的安全方法可能如下所示:


密码重置请求:

  1. 用户打开密码重设申请表并输入电子邮件地址(无需输入两次,只需进行语法验证)。

  2. 您的应用程序会检查您的数据库中是否存在该电子邮件。如果它存在,它会创建一个令牌,该令牌应该是随机的,而不是来自诸如userid或timestamp之类的信息。令牌的哈希将与用户ID和有效期一起存储在数据库中的单独表中。带有令牌的链接将通过电子邮件发送给用户。

  3. 该应用程序显示已发送电子邮件的确认。此页面可以包含电子邮件地址,因此用户可以检查他是否有拼写错误(毕竟没有关于电子邮件是否在数据库中的信息,以便攻击者无法测试其存在)。

  4. 密码重置:

    1. 用户点击该链接并打开重置表单。在此表格上,他可以输入两次新密码。必须将令牌作为隐藏输入标记包含在表单中。

    2. 提交表单后,应用程序会检查他的令牌。如果匹配且未过期,则可以更改密码并且用户可以直接登录(然后您可以为他提供登录表单)。最后应该停用令牌,我自己更喜欢保留该条目,因此当他再次点击该链接时,我可以通知用户该令牌已被使用。

    3. 您将遇到的一个问题是,您必须在数据库中找到令牌的哈希值。存储令牌有两种可能的方法:

      • 使用SHA512之类的哈希算法对令牌进行哈希处理,而不使用salt。如果令牌非常强大(最小长度为20,0-9 a-z A-Z),这是安全的。从理论上讲,在将数据输入数据库之前,必须检查这种哈希是否已经存在,实际上这可以忽略不计。我实现了可以处理此类令牌的password-reset class

      • 您使用BCrypt和salt哈希令牌。这允许更短的令牌,但您无法在数据库中搜索散列令牌。相反,您必须在链接中包含row-id才能找到令牌。