将电子邮件地址和密码都使用bcrypt哈希。

3

我正在建立一个匿名站点,用户的帐户不能被追溯到任何实际人员(例如通过电子邮件地址)。我想听听您对身份验证的想法。如果我使用电子邮件/密码组合进行身份验证,我是否可以使用bcrypt哈希电子邮件地址和密码(我知道这是可能的,但是否实用)?如果电子邮件地址被加密,那么在搜索数据库以查找匹配项时速度会非常慢,这是真还是假?您有什么想法?还有其他想法吗?基本上,对于如何进行身份验证,我对任何想法都持开放态度,但如果使用电子邮件进行身份验证,则无法暴露或解密。谢谢!

2个回答

1

我认为你的想法没有任何问题(假设您从未想过异步发送电子邮件给用户)。

登录:

  1. 用户提交登录表单,其中包含明文电子邮件和明文密码(当然使用良好的传输层安全(TLS)加密)
  2. 计算 eh = h(email), ph = h(password)
  3. 从用户数据库中提取 eh == stored_eh 的记录
  4. 将 ph 与 stored_ph 进行比较

忘记密码流程:在用户提交“忘记密码”表单并附带其明文电子邮件地址的那一刻,您就拥有了他的电子邮件地址。计算 eh,查找个人资料,生成一次性令牌,将其存储到个人资料中并放入邮件发送给他的电子邮件地址。然后,他可以使用该令牌定义新密码。

更改电子邮件流程:与上述类似,在表单提交时您拥有明文旧/新电子邮件地址。

注意事项:

  • 第3步中的数据库查找并不比使用明文搜索键慢。
  • 对于2和4,使用来自维护良好的库(scrypt、bcrypt、pbkdf2、sha512_crypt),而不仅仅是简单的盐哈希。
  • 如果攻击者获取了您的数据库并拥有潜在电子邮件地址列表,则可以轻松地确定您是否将其作为用户之一,并确定他们在您的数据库中的用户记录。 如果这是一个问题,您可以使用h(email+password),但那时就无法恢复密码了。

所以您的意思基本上是:1)如果我分别对电子邮件和密码进行bcrypt,它不会减慢身份验证查找过程;2)如果我分别对两者进行bcrypt,并且用户忘记密码,我仍然可以匹配帐户(因为电子邮件是单独哈希的),并使用最近输入的电子邮件进行恢复,以发送更改密码令牌。如果我不存储恢复电子邮件也不存储已发送的恢复电子邮件的日志...那么数据库仍然无法追踪? - Jeffrey
额,一些额外的注释:1)当然,它会因为计算一个更多哈希所需要的时间而变慢(例如bcrypt)。2)对于用户名,您希望每个哈希计算为相同的用户名提供相同的哈希值,因此在这里不应使用盐[否则您将无法从数据库中查找记录]。对于密码,当然应该使用盐,以便具有相同密码的两个用户不具有相同的哈希值。 - Thomas Waldmann

1
一旦你对某物进行哈希,原始数据就无法恢复。
例如,当用户注册时,通常会使用bcrypt等工具对密码进行哈希处理,然后将哈希值存储在数据库中。这样很好,因为如果攻击者获取了数据库副本,就无法“解密”哈希值。
在你的情况下,你可能不希望对电子邮件进行哈希处理,因为这意味着你将永远无法给这个人发送电子邮件 - 我猜你想这么做。
如果你决定走这条路,基本上每个用户将需要存储两个密码(这是我能想到的最接近的比喻,抱歉!)。
希望这有所帮助!
编辑:更好的方法是仅使用密码创建一个新账户,然后自动生成用户名给该用户。像privateinternetaccess.com这样的公司就是这样做的--他们会为你生成一些随机的用户名--这样你就不能联系用户,但他们仍然可以安全地登录你的应用程序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接