实施“忘记密码”的最佳方法?[关闭]


153

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

我提出了两个想法:

  1. 当用户单击“忘记密码”时,要求用户键入用户名,电子邮件,并可能输入出生日期或姓氏。然后,带有临时密码的邮件将被发送到用户的电子邮件帐户。用户使用临时密码登录并重置密码。

  2. 与之类似,但电子邮件中将包含一个链接,以使用户重设密码。

还是有人可以建议我一种更好,更安全的方法?我也在考虑发送临时密码或链接,强制用户在24小时内重设密码,否则临时密码或链接将无法使用。怎么做?


我重新标记了该帖子,因为它超出了JSF的范围-您可能会以这种方式获得更多回复。
McDowell

6
@Whoever这几个月来在meta上有一波“让我们删除这个封闭的问题,因为XYZ”的浪潮。我只想在此指出,不应删除这个特定问题,除非已证明解决方案有缺陷,并且它的存在对安全性的帮助远不止于此。
费利克斯Gagnon的-格雷尼尔

1
OWASP“备忘单”,用于忘记的密码恢复策略:owasp.org/index.php/…–
daiscog

通过@megaflop建议的链接现在黯然破碎,这里是新的链接:cheatsheetseries.owasp.org/cheatsheets/...
马尔科BOLIS

Answers:


186

更新: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. 当用户单击电子邮件中的链接时,他将移至您的页面。该页面ID从URL中检索,再次对其进行哈希处理,然后对照该表进行检查。如果存在这样的记录,并且该记录不超过24小时,则提示用户输入新密码
  5. 用户输入新密码,单击确定,从此以后每个人都过着幸福的生活……直到下一次!

1
实现此目的的最合适方法是-将临时密码重置令牌作为纯文本电子邮件发送给用户(但切勿将其作为纯文本存储在数据库中)-用户输入此温度后,立即迫使他执行以下操作:重新输入新密码。-对于偏执狂,请确保您的smtp服务器具有ssl,因此不会窥探包含敏感信息的邮件。在大多数情况下,此方法非常安全。如果您的案件需要进一步的安全保护,则可能不应该让用户忘记他们的密码:S
Kaushik Gopal,

6
为什么要生成随机字符串/引导,对其进行哈希处理并使用哈希?引导不够吗?
Jeroen K

15
@jeroenk-这样,如果有人窃取了您的数据库,他将无法伪造“重置密码”链接并更改某人的密码。
Vilx-

4
这本质上是正确重置密码crackstation.net/hashing-security.htm#faq
TruthOf42

1
@David-Ach,我想编辑帖子,但主题已锁定。:(好吧,让我们再试一次:您的表将包含列:IDUserIDTimeTokenHash。你会产生两个长,随机字符串将第一个字符串(“ID”)在ID列;哈希第二(以下简称“令牌” ),然后将哈希值放在TokenHash列中。生成的链接类似,链接中forogotPassword.jsp?id=asdasd&token=asdasd的令牌未进行哈希处理。现在有意义吗?
Vilx-

28

这完全取决于您的站点和您要达到的安全级别,但是Web应用程序的基本过程如下所示:

  1. 用户导航到“忘记密码”页面,并输入其用户名或电子邮件(以唯一的为准)以请求重设密码。

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

  3. 查找用户的帐户。保存一个临时密码(通常为GUID)并为帐户记录添加时间戳。向用户发送包含临时密码的电子邮件。

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

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

这里的原则是向用户发送一个临时密码,让他们更改密码。最初存储的密码(应哈希!)永远不会更改为临时密码,以防用户记住。

原始密码将永远不会显示给用户,因为它应该是哈希值并且是未知的。

请注意,此过程完全取决于用户电子邮件帐户的安全性。因此,这取决于您希望达到的安全级别。对于大多数网站/应用程序而言,这通常就足够了。


24

特洛伊·亨特(Troy Hunt)在他的文章《构建安全密码重置功能的所有您想知道的东西》中提出了一些很好的观点。最相关的摘录是:

[T]以下是两种常见方法:

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

尽管有许多相反的指导,但第一点实际上并不是我们想要达到的目标。这样做的问题在于,这意味着永久密码(您可以随时使用并可以随时使用的密码)已经通过不安全的通道发送并驻留在您的收件箱中。

...

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

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

...

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

...

我们想对重置URL进行的另一件事是对令牌进行时间限制,以便重置过程必须在一定时间内(例如一小时内)完成。

...

最后,我们要确保这是一个一次性的过程。重置过程完成后,应删除令牌,以便重置URL不再起作用。与上一点一样,这是为了确保攻击者拥有一个非常有限的窗口,他们可以在其中滥用重置的URL。另外当然,如果重置过程已成功完成,则不再需要令牌。

他在避免信息泄漏,验证码,两因素身份验证,以及基本的最佳实践(例如密码哈希)方面提出了很多其他要点。我认为重要的是要指出,我不同意特洛伊关于安全性问题的用处,而更喜欢布鲁斯·施耐尔(Bruce Schneier)对这种做法的怀疑

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


1
该链接具有清晰的NSFW图像,有一个链接可以更改此图像,但是很多人首先扫描页面。愚蠢的主意!
nik0lai 2014年

特洛伊·亨特(Troy Hunt)的文章的链接已更改。转到troyhunt.com/您想要知道的一切
knarfancho

@knarfancho固定,谢谢!
Dave Liepmann

15

我会去:

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

我不想惹麻烦?但这与您的答案有关。您如何生成GUID?
KingAndrew 2011年

2
-1表示未在您发送给该人的链接上实现某种哈希
TruthOf42

11

通过电子邮件发送任何信息时,它是不安全的。有人可以通过多种方式获得它。对于希望窃取您的信息的熟练黑客来说,这将是小孩子的游戏。

请勿通过电子邮件发送任何个人信息,例如密码和收入信息,因为如果这些信息泄漏或被盗,对您和您的组织而言,这将变得非常困难。认真考虑安全性。只需发生一次事件,所有积木就掉下来。

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

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

编辑:更新的链接



我尝试了“忘记密码最佳实践”的链接,但收到500个服务器错误。您是否认为服务器当前已关闭,或者是否还有其他链接可循?
KingAndrew 2011年


链接再次消失。
Eric Cope 2013年


7

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

  • 在确认用户身份(安全性问题,电子邮件地址等)后,显示临时密码的一半,然后将另一半发送到电子邮件帐户。如果电子邮件帐户已被盗用,则同一个人不太可能还会进行中间人攻击。(在英国政府门户网站上看到)

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

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


6

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

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



4

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

然后,将链接发送到允许该人更改密码的临时页面很简单。(允许不超过24小时)

在这种情况下,用户的电子邮件帐户是最弱的链接。


2

切勿通过电子邮件将密码发送给用户。即使它是自动生成的。最佳方法(SANS和其他人推荐和使用):

  1. 在“忘记密码”页面上,询问用户的电子邮件/用户名和新密码。
  2. 通过激活链接将链接发送到该帐户的已存储电子邮件。
  3. 当用户单击该链接时,请启用新密码。

如果他没有在24小时左右内单击链接,请禁用该链接(以使其不再更改密码)。

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


13
我担心这种技术。攻击者输入您的电子邮件和新密码。帐户所有者收到电子邮件,误读了一些内容,然后单击链接。攻击者待命,每分钟尝试输入新密码,可以访问该帐户,直到帐户所有者意识到发生了什么,最终进入“忘记密码”页面。
Odi-Xceed

另一个问题!在密码重置时间上提供新密码不是一个好的选择。如果下班后检查我的电子邮件,我可能会再次忘记新密码!
Yazid Erman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.