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

149 security authentication passwords forgot-password

我正在寻找实现"忘记密码"功能的最佳方法.

我提出了2个想法:

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

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

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

Vil*_*lx- 182

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

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

  • @jeroenk - 如果有人窃取您的数据库,他就无法伪造"重置密码"链接并更改某人的密码. (14认同)
  • 为什么生成一个随机字符串/ guid,哈希并使用哈希?指导不够吗? (5认同)
  • 这基本上是正确重置密码的描述方式https://crackstation.net/hashing-security.htm#faq (4认同)

Dav*_*enn 28

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

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

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

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

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

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

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

原始密码永远不会显示给用户,因为它应该是散列和未知的.

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


Dav*_*ann 21

Troy Hunt在他的文章中提出了一些很好的观点,即你想要了解的关于构建安全密码重置功能的所有内容.最相关的摘录是:

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

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

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

...

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

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

...

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

...

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

...

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

他在避免信息泄漏,CAPTCHA,双因素身份验证以及密码哈希等基本最佳实践方面提出了许多更好的观点.我认为值得注意的是,我不同意特洛伊关于安全问题的有用性,更喜欢布鲁斯施奈尔对这种做法持怀疑态度:

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

  • 该链接有清晰的 NSFW 图像,有一个链接可以更改此设置,但很多人会先扫描页面。愚蠢的想法! (2认同)

and*_*ana 15

我会去:

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

  • -1用于在发送给该人的链接上未实现某种哈希 (2认同)

jin*_*ngy 11

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

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

至于密码检索,请仔细阅读忘记密码最佳实践.

最重要的是,遵循最佳实践的应用程序应允许用户重置自己的密码.应该使用个人安全问题.应用程序不应发送电子邮件,显示密码,也不应设置任何临时密码.

编辑:更新链接


Tom*_*ner 7

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

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

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

对于这两个极端之间的某个地方实施安全问题可能是DaveG提到的方式.


Too*_*the 6

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

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


And*_*rry 5

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

然后发送一个链接到一个允许用户更改密码的临时页面的链接就很简单了。(允许 24 小时或更短)

在这种情况下,用户的电子邮件帐户是最薄弱的环节。


Kin*_*rew 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

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