当有人丢失密码时,他们单击丢失或忘记的密码链接。他们需要输入他们的电子邮件地址,然后回答他们自己的秘密问题。如果机密问题是正确的,将向他们发送一封电子邮件,其中包含一个在24小时后过期的链接。
发送电子邮件时,将在数据库表中输入一条记录,其中包含以下信息:-需要重置密码的人的电子邮件-密码重置将过期的小时-请求保留密码的时间已提交。
发送的链接将引导用户找到一个允许他们输入新密码的表单。在此表单中,他们需要输入他们的电子邮件地址和密码x2。
当他们单击Submit时,会对DB进行检查,以确保电子邮件有效(密码正在重置)且尚未过期(通过比较两个日期以查看是否已超过到期时间,即24小时)。
如果电子邮件有效且尚未过期,并且两个密码匹配并满足最低要求,则应用新密码。
成功时给出确认消息。
Q1。这是一个很好的密码恢复模式吗?Q2。如何确保发送到用户地址的链接是唯一的?没有人会得到同样的链接?因此,没有人可以直接进入密码重置页面,尝试不同的电子邮件,而是让每个需要重置的帐户都有自己的唯一URL,仅对该帐户有效。
关于第二季度:
我在想,当用户请求重置密码时,会生成一个随机的唯一ID,并存储在24小时后过期的同一个记录中。此随机唯一ID的列可以称为"rid"
将发送给用户的电子邮件中的链接将以结束?RID=XXXXXXXXXXXX
当用户在重置密码的页面中单击提交时,页面顶部的"rid"用于从数据库中获取相应的电子邮件地址,以将其与表单中的电子邮件地址进行比较。这样做可以确保每个密码重置案例都有自己的唯一URL,其他帐户无法使用该URL重置其密码。
这是可行的解决方案吗?
如有任何贡献或建议,将不胜感激。
最佳:好的。
通过openid登录。更少的编码复杂性,更少的点击,更少的打字,更少的浪费时间。
完成。问题是没有意义的。不用再担心了,已经有人解决了这个问题。
有10亿个站点实施了10亿个认证方案,99.999%的情况下是不必要的。为什么我作为一个用户应该信任你作为一个开发人员,不把我的密码以纯文本的形式存储,或者泄露它,或者自己被黑客攻击?很少有人对每个网站使用不同的密码…好的。
如果这不可能,那么make将尽可能地轻松:好的。
我单击"忘记密码?"链接。如果我已经输入了电子邮件(例如,在尝试登录失败后),这将自动发送邮件。如果我没有输入密码,只需隐藏密码字段并告诉我这样做。不要重新加载或将我转发到其他页面。
我用一些键(例如https://site.com/account/reset?key=a890ea8219175f890b7c123ee74a22)得到一个到的链接。一些独特的散列,绑定到我的帐户,在这么多小时后过期。尽可能使用SSL。
我点击这个链接,你就可以通过这个键来获取我的账户详细信息,确保它是有效的并且没有过期。我输入了两次新密码。我已经知道我的电子邮件地址是什么,你已经知道我的电子邮件地址是什么,任何可能的黑客也会知道我的电子邮件是什么,所以不要让我输入它。让链接持续一整天太过分了。一个小时或更短的时间。
我讨厌安全问题。别问我这个问题。基本上,这只是第二个故意降低安全性的密码,所以你会一直记住它。我没有经常飞行的英里数,我不知道我母亲的娘家姓等等。停下来。我知道这是为了阻止那些可能侵入你的电子邮件的陌生人,但是除非你是贝宝,我认为这只是工程。
当您确认密码匹配并且可以接受时,请更新数据库(只存储我的密码的一个盐散列,而不是密码本身!)马上给我登录。不要将我重定向到登录页面,在那里我必须重新输入我已经给过你几次的信息(即使你已经知道是我,并且足够信任我来更改我自己的密码)。那太烦人了。用户不耐烦。
我也不喜欢基于以下内容随机生成的密码:好的。
通常我只是从邮件中复制粘贴密码。复制粘贴密码是您不希望用户做的事情。
我必须手动更改密码,这意味着在用户控制面板或帐户设置或其他任何地方乱搞。我越来越不耐烦了!当我用一次性密码登录时,你可以用"更改密码"来加快速度,但这意味着增加了代码复杂性。现在您需要为此添加一个标志,添加另一个重定向,处理用户在输入新密码时超时的情况,等等。
因为我只是人类,人类有多动症,我通常忘记做以上的事情,最后我得到了一个垃圾密码,我必须在下次登录时从我的电子邮件中找到并复制。我的错,但我还是要怪你的网站。;-)
随机生成的密码解决方案也意味着,当基于链接的身份验证在可用性和安全性方面似乎是未来(OpenID等)时,您将始终使用基于密码的解决方案(我不想让100个小站点知道我的登录详细信息!).好的。
更新以响应评论:好的。
为什么哈希足够:如果一个黑客能猜出你生成的哈希的全部128+位(比如说一个小时内),那么他或她为什么不能猜出电子邮件呢?我知道询问电子邮件和/或安全问题"感觉"更安全,但是如果你考虑一下,电子邮件通常是非常可预测和统一的,熵率很低。我怀疑它们能被认为包含超过50位的信息。(可能要少得多)我敢打赌,我猜你的电子邮件比我猜一个50位的随机整数还快。但如果这是一个真正的担忧,你所需要做的就是在散列中添加更多的位。对于过杀模式——SHA256(salt, email, old pw hash, time stamp, maybe some bytes from /dev/urandom)或类似模式,应该是256位左右。如果一个黑客能预测到这一点,那么你真的做不了什么。很明显,他可以控制矩阵,如果他愿意的话,他可以把他的思想投射到硬盘里的磁性盘片上。好的。
仍然支持openid:我访问的任何一个新网站,如果我要求创建一个用户,那么他们为什么想知道我的(一次性)密码,以及他们在安全方面为我提供的,openid或google/facebook/etc.不信任我的(一次性)密码,或者他们为什么不信任google/facebook/etc.没有人(我知道)会记住30个不同的密码。通常人们会重用它们,所以如果这些第三方网站创建者想这样做,那么他们就很容易欺骗他们的用户。如果我在你的网站注册了我通常的信息,你可以立即接管我的last.fm和reddit帐户,如果你愿意的话,还有可能十几个网站,我已经用了几次,忘记了。事实上,在当今时代,我有点期望站点如果想要他们严格不需要的细节,要么无知,要么有恶意意图,所以这就是我称之为一次性密码的原因——每次注册时,我都会说"这里,有我的reddit帐户,它和我将用于您的站点的L/P相同(否则我会忘记)。很好,我并不是特别喜欢它。"当然,如果他们愿意的话,谷歌可以接管我在线上的一切,但现在我会比你更信任谷歌(没有冒犯之意!).好的。好啊.
- 我不同意OpenID解决方案。从用户的角度来看,输入用户名和密码并单击"提交"比重定向到另一个网站、搜索URL(wtf?为什么我不能只用我的短用户名,必须输入这个长URL?),输入密码,单击"提交",然后再次重定向。
- 我唯一的分歧是在第三步。我必须确认我不是偷了这个网址或者随机找到它(通过输入我的用户名/电子邮件)。这样就消除了"钥匙"薄弱或可预测的风险。还有,openid上的+1,虽然这也是"一封已经存档的电子邮件"的一种形式——它只是通过第三方而不是用户的身份验证。
- @美因玛:这只是一个糟糕的实现。尝试从stackoverflow.com注销并重新登录。对我来说,只需点击一个链接,它就会自动登录(因为我已经用谷歌登录了)。应该这样做!
- @杨:是的,但这是一种权衡,在几乎所有的情况下,我都会选择一个不需要我再打一次电子邮件的网站(我觉得我每天需要打五次,我已经厌倦了)。我已经相信这个网站不会泄露你的个人信息/纯文本密码/电子邮件,所以相信他们能够成功地生成一个密钥是一个较短的信念飞跃(至少对我来说)。
- +我完全同意这个秘密问题。这只是第二个故意不安全的密码。(这是愚蠢的)
- stackoverflow.com/questions/3191531/how-safe-is-openid我看到需要删除安全问题。为什么我要在密码重置窗体中询问电子邮件?为了防止黑客猜到唯一的重置URL,黑客还必须猜到匹配的电子邮件。数据在数据库中散列,格式为ssl。
- 我不明白这个链接。我把它理解为OpenID的模糊论点?不管怎样,如果你感兴趣并且仍然不相信的话,我会用更多的论据来更新答案。我找不到直接给他们留言的方法。
首先,我建议您将密码重置视为安全的业务事务。并且单个请求独立于同一帐户的其他请求。生成一个随机的、不可重用的事务ID,并将其与此密码重置请求关联。然后,在您发送给他们的电子邮件中,使用URL嵌入事务ID:
http://www.yoursite.com/passwordreset/?id=e3dXY81fr98c6v1。
这个所谓的密码重置事务应该与帐户相关联,并将元数据与密码重置相关联,例如请求日期和到期日期。帐户本身应该只知道有/有与之相关联的挂起的密码重置。
另外,当用户要求重置密码时,忘记这个秘密问题——向他们发送一封您应该已经存档的电子邮件要安全得多。(如果没有,那么就开始收集它们!)-更好的是,使用他们的电子邮件地址作为用户名。
当用户从该事务ID URL输入新密码时,您会相信它是您认为的人。为了确保这一点,您可以简单地要求他们重新输入他们的用户名(您已经确认了这一点)。
- 是的,SSL是个好主意,我忘记提了。
- 秘密问答将被揭晓。你所指的那封电子邮件应该已经存档了,是不是会有唯一的URL?
- 对。文件中的电子邮件地址是接收链接的地址。
Q1。嗯,有一个缺陷。为什么要求用户输入新密码?我宁愿生成一个新的随机密码并发送给他。收到密码后,用户可以使用随机生成的密码登录,然后在其配置文件中更改密码。
我建议在大多数网站上使用以下系统:
用户在"密码重置"窗体中输入邮件地址。
邮件已验证(即数据库中是否有具有此邮件地址的用户?)
新密码是随机生成并通过邮件发送的,然后进行盐渍/散列并保存到数据库中。
用户登录。
这很容易,也很常见,所以用户不会丢失。
现在,您可以通过以下方式提高安全性(减少滥用):
- 设置密码重置比率。一旦提交了表单,就会记住IP地址和提交的数据:现在,在几分钟内,来自同一IP地址的任何人都不能再重置密码。
- 新生成的密码不能替换旧密码:相反,两者都可以使用。假设有人重置了另一个用户的密码。如果该用户没有阅读或收到带有新密码的邮件,则该用户必须仍然能够使用旧密码登录。
顺便说一句,但这只是我个人的意见,除非需要,否则不要提供秘密的问答功能。我有太多的痛苦记得我在哪里回答了什么,所以我可能比密码更容易忘记答案。
- +我讨厌秘密问题…首先,我提供了答案,后来在我的信息框里把它贴到Facebook上。像"母亲的娘家姓"或"我长大的城市"这样的东西太容易研究了。其次,我很少记得我提供的答案…基本上,我觉得它降低了拥有安全密码的安全性。此外,您已经知道电子邮件是合法的(因为这是它注册的),所以为什么不发送一个电子邮件链接重置,等等。
- 你看到了什么缺陷?发送一个适合一次登录的随机密码,或一个适合一次登录的随机链接,其安全性大致相同。链接的主要优点是用户可以简单地忽略错误的重置请求。如果您发送随机密码,他们必须对错误请求采取操作(将密码改回)。我也不认为同时拥有两个密码是个好主意。这将减轻暴力攻击,只是轻微的,但仍然如此。只要用户控制他们的电子邮件,他们就不必担心错误的重置。
- @MatthewFlaschen:缺陷是用户被要求输入密码。作为用户和开发人员,这对我来说都很奇怪。作为用户,我希望收到一个新的密码。作为一个开发人员,我不希望有相同的想法两次:你会有一个密码安全检查或提交数据控制在三页(注册+配置文件+密码更改)?如果密码足够长,生成随机密码不会增加蛮力风险。错误请求的坏处不是安全问题,而是用户收到太多邮件会很生气。
- 发送重置链接是一次性使用密码。这里唯一缺少的详细信息是,如果以前使用过链接,您应该在他们单击链接时向发出警报,并重置密码(因此可能有人已经发送了链接)。只要密码没有更改,链接也没有过期,这就不是问题。但是,如果您按照链接操作,并且密码已经重置,那么您就有了一个潜在的问题。处理这有点像泡菜(因为用户可能只是在以后不小心点击了链接)。
- 另外,一个人对自己的电子邮件没有完全的控制权,大多数电子邮件都是通过互联网以透明的方式传输的。窃听器、爱管闲事的管理员、共享计算机的人都是从电子邮件中获取敏感信息的载体。我建议的另一件事是,每次更改密码时都不要向帐户持有人收费。所以,正常的重设处理会让用户看到重设邮件,然后密码更改通知邮件。如果他们在单击链接之前看到密码更改,就会出现问题。在"所有者"更改之前发送电子邮件。
- 好吧,我同意你的看法。事实上,最好只发送一个ID(一个包含用于重置的ID的URL),而不是纯文本格式的新密码。
- 生成新密码是个坏主意。可能是你的密码生成策略有缺陷,等等。我认为这不是一个好方法。
- 拥有一个有缺陷的密码生成策略是一个坏主意。;)
- 您已经介绍了系统不应该生成密码的原因。秘密问答将被揭晓。双重密码感觉不对。