2010-05-03 77 views
6

以邮寄重置用户密码的正常流程是这样的:密码,不需要数据库表通过电子邮件重置

  1. 生成一个随机字符串,它
  2. 电子邮件字符串存储在数据库中的表用户
  3. 用户单击包含字符串的链接
  4. 字符串针对数据库进行了验证;如果匹配,用户的密码被重置

但是,维护一个表和过期的旧字符串等似乎有点不必要的麻烦。这种替代方法有没有明显的缺陷?

  1. 生成用户现有密码的MD5哈希
  2. 电子邮件哈希字符串用户对包含字符串
  3. 字符串link
  4. 用户点击由现有的PW再次验证散列;如果匹配,用户的密码被重置

请注意,用户的密码已存储在哈希和盐渍的形式,我只是再次哈希它得到一个唯一但可重复的字符串。

是的,有一个明显的“缺陷”:因此生成的重置链接将不会过期,直到用户更改其密码(单击链接)。我真的不明白为什么这会是一个问题 - 但如果邮箱遭到破坏,用户仍然会受到干扰。而且没有重用的风险,因为一旦用户的密码被更改,重置链接将不再匹配。

+1

+1的有趣想法 – 2010-05-03 03:04:40

回答

8

要修正obvious flaw,将当前日期(以及更多与时间相关的信息表示一天中当前的一小部分,如果一天的时间太长)添加到哈希值以生成神秘字符串并检查它 - 这会使字符串“过期”(如果你想要更长的时间,你可以检查以前的日期和分数)。所以在我看来,你的计划是非常可行的。

+0

啊你打我吧;)。只要确保使用数据取决于用户时区:) – 2010-05-03 01:25:04

+0

如何从用户提交的散列中派生到期日期以检查当前日期是否过去?它将不得不被加密和加固。否则:A)你只是编码它,用户打破编码,甚至有时间检查的目的失败。 B)你把它作为明文,一样的东西。如果你有全局秘密S来避免空间浪费,你可以发送用户'HASH(S || time || userpass)','time';用户发送'hash','time',这将允许服务器测试'HASH(S || time_user_sent_back || userpass)'用户发回的哈希。 – 2010-05-03 02:30:39

+2

@Longpoke,如果(例如)字符串应该在'2010/05/06'和'2010/05/07'上有效,那么你可以将'2010/05/06'追加到你正在哈希化的字符串中 - 而已。在检查时,你可以通过追加今天和昨天的ISO格式来检查你获得的哈希 - 就是这样,几乎没有火箭科学。如果您希望特定字符串到期时的粒度超过一天,那么您还可以使用适当的day_的_fraction,例如如果你想让字符串持续大约1.5天,那么使用哈希(和检查3种可能性)之间的“半天”(例如AM或PM) - 也不难! – 2010-05-03 02:47:27

3

如果有人使用密码哈希访问数据库,他们不知道实际的密码。如果你实现这个系统,那么他们可以生成重置链接并自行重置密码。使用随机字符串和折中知识,可以使所有随机字符串无效,并且只有在重置密码过程中的用户即使不知道访问权限也会受到影响。不是可能的情况,但考虑到随机字符串的名义开销,可能值得考虑。

+0

一旦您的站点遭到入侵,您也希望重置所有密码,因为攻击者可能在将它们提交给服务器时以明文形式记录它们(一种不可避免的情况;只有SSL客户端证书可以阻止此情况)。更不用说攻击者可能在几个小时内破解了90%的哈希密码。 另外,如果你使用亚历克斯·马尔泰利的建议,你可以添加额外的检查重置请求与妥协时间,这实际上是相同的,你只是建议:) – 2010-05-03 02:45:50

+0

除了不是每个用户将有一个随机字符串但每个用户都有一个生成的字符串,所以如果您没有立即意识到妥协,只有少数用户受到影响。当然,除了密码较弱的90%以外。 – drawnonward 2010-05-03 03:17:37

+0

嘎!这绝对是一个真正的漏洞,尽管正如Longpoke所说,一旦攻击者进入数据库,所有的注单都将关闭:他们不需要重置链接,他们可以直接在用户表中更改密码。 +1虽然找到它! – jpatokal 2010-05-03 05:02:39

2

其实在再次考虑这个之后,你的方法可能是少于比“正常流量”安全。

如果你只是发回HASH(HASH(user's original password)),我可以看到场景中这可能使攻击者利用:

方案1:您的网站为[email protected]

  1. Jim寄存器。
  2. Jim要求重置密码,但不使用它。重置电子邮件留在他的收件箱中永恒。
  3. Jim更改您的网站上的他的电子邮件地址。
  4. [email protected]受到Bob的影响。
  5. Bob现在通过其分布式GPGPU场进行暴力破解,并恢复Jim的密码。

方案2:

  1. Jim使用密码jimjonesupinthisma!他的银行帐户。
  2. Jim在您的网站注册为[email protected][email protected]而不是以任何方式与Jim的银行帐户关联。
  3. [email protected]受到Bob的影响。
  4. Bob现在要求重置,他现在有HASH(HASH(jim's password))
  5. Bob现在通过他的分布式GPGPU场进行暴力破解,并且恢复了Jim的密码,然后他用它来访问Jim的银行帐户。

方案3:

(你的网站使用TLS,用户通过TLS注册。)在您的网站为[email protected]

  1. Jim寄存器。
  2. Bob要求在Jim的帐户重置密码。
  3. Bob适用于国家安全局Room 641A
  4. Bob使用他的全球互联网嗅探器,并获得HASH(HASH(jim's password)),因为它的电子邮件以明文形式发送到[email protected]
  5. Bob现在通过其分布式GPGPU场进行暴力破解,并恢复Jim的密码。

情景1和情景2的变化总是发生(取决于散列和密码的强度),我不太确定3.问题是,您的方法会榨取不必要的信息,这确实可以利用攻击者攻击你的用户。

我建议你使用随机生成的令牌没有什么来处理用户的密码。

+0

对不起,我不同意这里:所有的场景似乎都认为两次腌制和散列的字符串对恢复原始字符串有任何用处,但这似乎并不是这种情况。已知MD5容易受到碰撞攻击,但您的假想黑客需要成功的原像攻击才能从密码中取回密码。迄今为止已知的针对一轮无盐MD5的最佳攻击具有2^123的复杂度,即使这种攻击牢固地落在科幻小说领域。 – jpatokal 2010-05-03 04:59:10

+0

你不需要(通常不希望)碰撞,只需要一个密码(通过字典,然后通过1-n数字后退到charset的暴力破解)。大多数用户都有弱密码,没有散列真的可以保存它们。这些攻击是真实的,尽管不像你听说的典型的脚本小子攻击那样普遍。事实上,这更多的是在合适的时间做决定并在正确的地方。 – 2010-05-03 06:01:35

+0

这些攻击对于未加密的MD5是真实的,您可以在其中使用彩虹表反转哈希,但此处的密码会被盐渍和双重哈希。 – jpatokal 2010-05-03 23:32:07

0

比方说,在非常罕见的情况下,即使在将随机盐串联到它之后,您的两个用户也拥有相同的哈希密码;会有问题吗?如果你将user_id的电子邮件或Hashid添加到重置密码链接,我想这不会有什么影响。

0

这个问题就过去了,有一个想法:

1)关于用户帐户信息发出一个JWT(JSON网络令牌)。令牌有一个过期,比如说1小时。

2)发送所述令牌的用户在电子邮件/链路

3)用户点击链接时,令牌被发送到服务器端点,令牌验证。如果有效,您解开令牌并更新用户帐户

此方法的任何缺陷?没有数据库被触摸(除了新的用户密码,如有必要)

+0

是的,您可以多次使用该令牌,但是我确定这一点。这是一件好事。我将令牌过期设置为1小时,所以滥用是不可能的。我错过了什么?它非常简单并且运作得非常漂亮,我一定错过了一些东西。 – Spock 2017-02-14 11:52:40

+0

另外,我会将请求的IP地址放入令牌中。然后,在验证时,匹配调用者的IP。然后令牌只能从发起请求的相同设备使用。这只是额外的措施。 IP欺骗者仍然需要令牌,并在1小时内。 – Spock 2017-02-14 12:02:29

相关问题