如果你在运行一个有很多用户的网络服务并且你被黑客入侵了,你可能会泄露用户的纯文本信息,比如电子邮件和密码哈希等哈希。
是否也值得将电子邮件地址存储为哈希值?
如果你在运行一个有很多用户的网络服务并且你被黑客入侵了,你可能会泄露用户的纯文本信息,比如电子邮件和密码哈希等哈希。
是否也值得将电子邮件地址存储为哈希值?
一般来说,您不应该询问和持有您不需要的用户数据(尤其是 PII),现在在 GDPR 下更是如此(如果它适用于您的场景),但在安全方面一直如此。数据越少,风险就越小。
当您对密码进行哈希处理时,您会失去对其纯文本版本的了解,并且您会询问是否值得对电子邮件和密码进行哈希处理,这让我认为您可能一开始并不真正需要这些信息。
话虽如此,如果您确实需要电子邮件(用于记录以外的其他目的),那么您不能对它们进行哈希处理,因为这样做会丢失该信息。在这种情况下,我建议使用AES / HMAC或Chacha20 / Poly1305或类似方法加密/验证您的数据。
另一种方法是使用PAKE:没有电子邮件,没有密码,也不需要通过 Internet 传输它们!这方面的一个例子可以是SRP或OPAQUE。
您需要问自己的第一个问题是,您的服务首先需要电子邮件地址吗?它需要该电子邮件地址做什么?
如果您不需要电子邮件地址,请不要存储它。
如果您需要知道电子邮件地址,并且如果哈希版本可以满足所有这些需求,那么只存储哈希值听起来是个好主意。
如果您需要知道电子邮件地址的目的是散列无法满足的,那么只存储散列不是一个好主意。例如,如果您需要向您的用户发送电子邮件,那么您可能无法仅使用散列来做到这一点。
散列电子邮件地址的实际用例。
想象一个用户可以使用他们的电子邮件地址和密码登录的网站。用户也可能有一个用户名,但这超出了这个答案的范围。
当用户登录时,他们输入他们的电子邮件地址和密码。为了让您在数据库中找到该电子邮件地址,哈希值就足够了。您可以只存储一个哈希值,然后在进行查找之前对用户提供的值进行哈希处理。
如果你只是做了一个普通的无盐哈希,这些值仍然可以在不同的站点之间进行比较(例如,如果使用这种方法的多个站点有数据泄漏)。另一方面,对每个用户使用唯一盐的散列是密码的最佳实践,也不起作用。将用户与数据库中的每个条目进行比较太低效了。
相反,您可以拥有一个不经常更改的站点范围的盐(例如每年一次),这样每次登录都可以使用您曾经使用过的每个盐值进行尝试。
这样您就可以通过电子邮件在数据库中查找用户,而无需存储该电子邮件地址。当然,您仍然使用密码散列来存储密码,每个存储的密码都有一个唯一的盐。
如果您想要发送密码重置电子邮件的功能,这也是可能的。当用户键入他们的电子邮件以接收密码重置电子邮件时,您可以像登录时一样在数据库中查找它。
如果您还希望用户在登录时可以看到用户的电子邮件,您可以在他们的浏览器中存储一个 cookie,并使用哈希作为密钥的电子邮件地址的加密版本。