“忘记密码”实施的最佳方式?

时间:2009-07-09 09:25:39

标签: security authentication passwords forgot-password

我正在寻找实施“忘记密码”功能的最佳方法。

我提出了2个想法:

  1. 当用户点击忘记密码时,用户需要输入用户名,电子邮件以及出生日期或姓氏。然后,具有临时密码的邮件将被发送到用户电子邮件帐户。用户使用临时密码登录并重置密码。

  2. 类似,但电子邮件中会包含一个允许用户重置密码的链接。

  3. 或者任何人都可以建议我更好更安全的方式?我也想发送临时密码或链接,强制用户在24小时内重置密码,否则临时密码或链接将无法使用。怎么做?

10 个答案:

答案 0 :(得分:165)

更新:2013年5月修订,以获得更好的方法

  1. 用户输入用户名并点击“忘记密码”。我还建议输入电子邮件地址而不是用户名,因为用户名有时也会被遗忘。
  2. 系统有一个表password_change_requests,其中包含IDTimeUserID列。当新用户按下按钮时,将在表中创建记录。 Time列包含用户按下“忘记密码”按钮的时间。 ID是一个字符串。创建一个长随机字符串(例如,GUID),然后像密码一样散列(这是一个独立的主题)。然后将此哈希用作表中的“ID”。
  3. 系统向用户发送一封电子邮件,其中包含一个链接。该链接还包含原始ID字符串(在散列之前)。链接将是这样的:http://www.mysite.com/forgotpassword.jsp?ID=01234567890ABCDEF。 forgotpassword.jsp页面应该能够检索ID参数。对不起,我不懂Java,所以我不能更具体。
  4. 当用户点击电子邮件中的链接时,他会移至您的网页。该页面从URL检索ID,再次对其进行哈希处理,并检查该表。如果有这样的记录并且不超过24小时,则会向用户显示输入新密码的提示
  5. 用户输入一个新密码,点击确定,所有人都过得很开心......直到下一次!

答案 1 :(得分:27)

这一切都取决于您的网站和您尝试实现的安全级别,但Web应用程序的基本过程如下所示:

  1. 用户导航到“忘记了我的密码”页面并输入用户名或电子邮件(无论哪个是唯一的)来请求重置密码。

  2. 可选择在此阶段,您可以通过询问其他信息(例如预定义安全问题的答案或出生日期等)来确认请求。此额外级别会阻止用户接收他们未请求的电子邮件。< / p>

  3. 查找用户的帐户。保存临时密码(通常是GUID)和帐户记录的时间戳。发送电子邮件给包含临时密码的用户。

  4. 用户点击包含临时密码的链接和电子邮件中的用户标识符,或导航到“忘记密码”页面并复制&amp;粘贴临时密码及其标识符。用户输入新密码并确认。

  5. 查找用户的记录,如果当前时间在步骤2中保存的时间戳的指定时间限制(例如1小时)内,则哈希并保存新密码。 (显然只有临时密码匹配!)。删除临时GUID和时间戳。

  6. 这里的主要是用户通过电子邮件发送一个临时密码,让他们更改他们的密码。最初存储的密码(它应该被散列!)永远不会更改为临时密码,以防用户记住它。

    原始密码永远不会显示给用户,因为它应该是经过哈希处理和未知的。

    注意此过程完全依赖于用户电子邮件帐户的安全性。因此,这取决于您希望实现的安全级别。对于大多数网站/应用来说,这通常就足够了。

答案 2 :(得分:19)

特洛伊·亨特在他的文章Everything you ever wanted to know about building a secure password reset feature中提出了一些很好的观点。最相关的摘录是:

  

[T]这里有两种常见的方法:

     
      
  1. 在服务器上生成新密码并通过电子邮件发送
  2.   
  3. 通过电子邮件发送一个有助于重置过程的唯一网址
  4.         

    尽管有相反的指导,但第一点并非我们想成为的地方。这样做的问题在于它意味着一个持久密码 - 您可以随时返回并使用它 - 现在已经通过不安全的渠道发送并驻留在您的收件箱中。

...

  

但是第一种方法还存在一个大问题,即它使得帐户的恶意锁定变得简单。如果我知道在某个网站上拥有某个帐户的人的电子邮件地址,那么只要我重新设置他们的密码,我就可以将其锁定。它是在银盘上提供的拒绝服务攻击!这就是为什么只有在成功验证请求者的权利之后才能进行重置的原因。

     

当我们谈论重置网址时,我们谈论的是一个网站地址,这个地址对于此重置过程的特定实例是唯一的。

...

  

我们要做的是创建一个唯一的令牌,可以在电子邮件中作为重置URL的一部分发送,然后与用户帐户旁边的服务器上的记录匹配,从而确认电子邮件帐户所有者确实是尝试的重置密码。例如,令牌可以是“3ce7854015cd38c862cb9e14a1ae552b”并且与执行重置的用户的ID以及生成令牌的时间一起存储在表中(稍后更多关于该令牌)。当电子邮件发出时,它包含一个URL,例如“Reset /?id = 3ce7854015cd38c862cb9e14a1ae552b”,当用户加载时,该页面会检查是否存在令牌,从而确认用户的身份并允许密码改变了。

...

  

我们想要对重置URL做的另一件事是限时令牌,以便重置过程必须在一定时间内完成,比如在一小时内完成。

...

  

最后,我们希望确保这是一次性过程。重置过程完成后,应删除令牌,以使重置URL不再起作用。与前一点一样,这是为了确保攻击者有一个非常有限的窗口,他们可以滥用重置URL。此外,如果重置过程成功完成,则不再需要令牌。

他在避免信息泄漏,CAPTCHA,双因素身份验证以及密码哈希等基本最佳实践方面提出了许多好处。我认为值得注意的是,我不同意特洛伊关于安全问题的有用性,更喜欢Bruce Schneier's skepticism of the practice

  

所有这些问题都是一样的:备份密码。如果您忘记了密码,秘密问题可以验证您的身份,以便您可以选择其他密码或让网站通过电子邮件将您当前的密码发送给您。从客户服务的角度来看,这是一个好主意 - 用户不太可能忘记他的第一个宠物的名字,而不是一些随机密码 - 但安全性很差。这个秘密问题的答案比一个好的密码更容易猜测,而且这些信息更加公开。

答案 3 :(得分:15)

我会选择:

  1. 向用户询问电子邮件,查看电子邮件已注册
  2. 生成GUID,并将其发送到该电子邮件
  3. 请勿重置密码
  4. 用户点击链接,然后必须输入新密码
  5. 仅在用户进入您的站点后重置密码,并在键入新密码后单击重置按钮。
  6. 使GUID在短时间内过期,以使其更安全。

答案 4 :(得分:11)

当您通过电子邮件发送任何信息时,它将不安全。有太多人可以获得它。对于想要窃取您的信息的熟练黑客而言,这将是孩子的游戏。

不要通过电子邮件发送任何个人信息,如密码和收入信息,因为如果此类信息被泄露或被盗,您和您的组织可能会变得非常尴尬。认真考虑安全问题。所有砖块都会发生一次事故。

至于密码检索,请仔细阅读Forgot Password Best Practices

  

底线是一个应用程序   应遵循以下最佳做法   用户重置自己的密码。   个人安全问题应该是   用过的。应用程序不应发送   电子邮件,显示密码,也不设置任何密码   临时密码。

编辑:更新了链接

答案 5 :(得分:7)

如上所述,这取决于所需的安全级别,但是,如果您需要更高级别,我所看到的一些新颖解决方案包括;

  • 确认用户身份后的一半临时密码(安全问题,电子邮件地址等),然后将另一半发送到电子邮件帐户。如果电子邮件帐户遭到入侵,则同一个人也不可能设法执行中间人攻击。 (见英国政府门户网站)

  • 通过电子邮件和其他媒介确认身份 - 例如通过文本发送到已注册移动设备的代码。 (见eBay / PayPal)

在这两个极端之间的某个地方实施安全问题可能是DaveG提到的方法。

答案 6 :(得分:6)

如果您在注册时包含电子邮件地址。 “忘记密码”按钮会向该电子邮件地址发送电子邮件。它确保将信息发送到受信任的电子邮件。

(除非数据库被黑,但没有什么是安全的)。

答案 7 :(得分:5)

以下是三个非常好的链接,提供有关密码重置的信息:

  1. http://jtauber.com/blog/2006/03/20/account_management_patterns/

  2. (不要让用户确认使用GET):http://www.artima.com/forums/flat.jsp?forum=106&thread=152805&start=15&msRange=15

  3. http://fishbowl.pastiche.org/archives/docs/PasswordRecovery.pdf

  4. 希望有所帮助。他们确实帮助我理解了这个问题。

答案 8 :(得分:4)

我会在帐户中强制使用唯一的电子邮件地址。

然后,只需将链接发送到允许此人更改密码的临时页面即可。 (允许24小时或更短时间)

用户的电子邮件帐户是此方案中最薄弱的环节。

答案 9 :(得分:3)

切勿向用户发送密码。即使它是自动生成的。最佳方法(由SANS和其他人推荐和使用):

  1. 在忘记密码页面上,询问 电子邮件/用户ID和新密码 来自用户。
  2. 通过电子邮件发送存储电子邮件的链接 对于具有激活的帐户 链接。
  3. 当用户点击该链接时, 启用新密码。
  4. 如果他未在24小时左右点击链接,请禁用该链接(以便不再更改密码)。

    未经用户同意,切勿更改密码。这意味着不要仅因为有人点击忘记密码链接并找出帐户名称而不通过电子邮件发送新密码。