首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何实现密码重置?

如何实现密码重置?
EN

Stack Overflow用户
提问于 2009-03-20 01:23:20
回答 7查看 31.2K关注 0票数 81

我正在用ASP.NET开发一个应用程序,我特别想知道,如果我想创建自己的Password Reset函数,我该如何实现它。

具体地说,我有以下问题:

  • 生成难以破解的唯一ID的好方法是什么?
  • 应该给它附加一个计时器吗?如果是,应该记录多长时间?
  • 我应该记录IP地址吗?这有什么关系吗?
  • 我应该在“密码重置”屏幕下询问什么信息?只有电子邮件地址吗?或者电子邮件地址加上一些他们“知道”的信息?(最喜欢的球队,小狗的名字等)

还有其他我需要注意的事项吗?

NBOther questions拥有完整的glossed over技术实现。事实上,公认的答案掩盖了血淋淋的细节。我希望这条问题和随后的答案会深入到血淋淋的细节中,我希望通过将这条问题的措辞更狭隘,我希望答案不是那么“空洞”,而是更“血腥”。

MVC :如果回答还涉及到如何在 Server中建模和处理这样的表,或者任何指向答案的ASP.NET 链接,我们将不胜感激。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2009-04-02 21:55:24

这里有很多好的答案,我不再重复了……

除了一个问题,这里几乎每个答案都重复了这个问题,尽管它是错误的:

Guids (实际上)是唯一的,在统计上是不可能猜测的。

这不是真的,GUID是非常弱的标识符,应该使用而不是来允许访问用户的帐户。

如果你检查这个结构,你最多只能得到128位...这在当今并不多见。

其中前一半是典型的不变(对于生成系统),剩下的一半是时间依赖的(或其他类似的东西)。

总而言之,这是一种非常脆弱和容易受到暴力侵害的机制。

所以不要用那个!

相反,只需使用加密的强随机数生成器(System.Security.Cryptography.RNGCryptoServiceProvider),并获得至少256bit的原始熵。

所有其他的,正如许多其他答案所提供的那样。

票数 66
EN

Stack Overflow用户

发布于 2009-03-30 20:29:21

编辑2012/05/22:作为这个流行答案的后续,我自己在这个过程中不再使用GUID。像其他流行的答案一样,我现在使用自己的散列算法来生成要发送到URL中的密钥。这也有更短的优点。查看System.Security.Cryptography以生成它们,我通常也使用SALT。

首先,不要立即重置用户的密码。

首先,当用户请求密码时,不要立即重置密码。这是一个安全漏洞,因为有人可能会猜测电子邮件地址(即您在公司的电子邮件地址),并随意重置密码。这些天的最佳实践通常包括向用户的电子邮件地址发送一个“确认”链接,确认他们想要重置它。此链接是您要将唯一密钥链接发送到的位置。我发送了我的链接,如下所示:domain.com/User/PasswordReset/xjdk2ms92

是的,在链接上设置一个超时时间,并将密钥和超时时间存储在你的后端(如果你正在使用的话,还要存储salt )。3天的超时是常态,当用户请求重置时,请确保在web级别通知3天。

使用唯一的哈希键

我之前的回答是使用GUID。我现在正在编辑这篇文章,建议大家使用随机生成的散列,例如使用RNGCryptoServiceProvider。并且,确保从散列中删除任何“真正的单词”。我记得有一次早上6点的特殊电话,一位女士收到了开发人员在她的“假设是随机的”散列密钥中的某个"c“字。多!

整个过程

  • 用户单击"reset“password”reset“password。
  • 用户被要求发送电子邮件。
  • 用户输入电子邮件并单击发送。不要确认或拒绝电子邮件,因为这也是不好的做法。简单地说,“如果电子邮件经过验证,我们已经发送了密码重置请求。”
  • 你可以从RNGCryptoServiceProvider中创建一个散列,将其作为一个单独的实体存储在一个ut_UserPasswordRequests表中,并链接回用户。这样你就可以跟踪旧的请求,并通知用户旧的链接已经expired.
  • Send了电子邮件的链接。

用户获取链接,如http://domain.com/User/PasswordReset/xjdk2ms92,然后单击它。

如果链接通过验证,则要求输入新密码。简单,用户可以设置自己的密码。或者,在这里设置你自己的密码,并在这里通知他们他们的新密码(并通过电子邮件发送给他们)。

票数 67
EN

Stack Overflow用户

发布于 2009-03-30 19:58:26

首先,我们需要了解您已经知道的有关用户的信息。显然,您有一个用户名和一个旧密码。其他你还知道些什么?你有电子邮件地址吗?你有关于用户最喜欢的花的数据吗?

假设您有用户名、密码和工作电子邮件地址,您需要向用户表中添加两个字段(假设它是一个数据库表):一个名为new_passwd_expire的日期和一个字符串new_passwd_id。

假设您有用户的电子邮件地址,当有人请求重置密码时,您可以按如下方式更新用户表:

代码语言:javascript
复制
new_passwd_expire = now() + some number of days
new_passwd_id = some random string of characters (see below)

接下来,向该地址的用户发送一封电子邮件:

亲爱的某某

有人为的用户帐户请求了新密码。如果您确实请求了此密码重置,请访问此链接:

http://example.com/yourscript.lang?update=>

如果链接不起作用,您可以转到http://example.com/yourscript.lang并在表单中输入以下内容:

如果您没有请求密码重置,您可以忽略此电子邮件。

谢谢,呀

现在,编写yourscript.lang:这个脚本需要一个表单。如果在URL上传递了var更新,则表单仅要求提供用户的用户名和电子邮件地址。如果更新未通过,它将要求提供用户名、电子邮件地址和电子邮件中发送的id代码。您还要求输入新密码(当然是两次)。

要验证用户的新密码,您需要验证用户名、电子邮件地址和id代码是否完全匹配,请求是否尚未过期,以及两个新密码是否匹配。如果成功,则将用户的密码更改为新密码,并从用户表中清除密码重置字段。还要确保用户注销/清除所有与登录相关的cookie,并将用户重定向到登录页面。

从本质上讲,new_passwd_id字段是一个只在密码重置页面上有效的密码。

一个潜在的改进:你可以从电子邮件中删除。“有人请求为此电子邮件地址的帐户重置密码....”从而使用户名在电子邮件被截取的情况下只有用户知道。我不是以这种方式开始的,因为如果有人攻击帐户,他们已经知道用户名。这增加了隐蔽性,阻止了中间人的机会攻击,以防有人恶意截获电子邮件。

至于你的问题:

生成随机字符串:它不需要非常随机。任何GUID生成器甚至md5(concat( salt,current_timestamp()都是足够的,其中salt是用户记录上的内容,比如创建了时间戳帐户。它必须是用户看不到的东西。

定时器:是的,你需要它来保持数据库的正常运行。不超过一周是必要的,但至少2天,因为你永远不知道电子邮件延迟会持续多长时间。

IP地址:由于电子邮件可能会延迟数天,因此IP地址仅用于日志记录,而不用于验证。如果你想记录它,那就做吧,否则你就不需要它了。

重置屏幕:见上文。

希望这样就可以了。祝好运。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/664673

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档