为什么人们在存储用户名之前不对其进行哈希和加盐

信息安全 密码 密码学 哈希 密码管理
2021-08-12 18:22:35

每个人都知道,如果他们的系统需要密码才能登录,他们应该存储所需密码的哈希和加盐副本,而不是明文密码。

我今天开始想知道的是,为什么他们不将用户 ID 存储在类似的散列和加盐密码中?

对我来说,这似乎是合乎逻辑的,因为我看不到任何缺点,而且如果数据库被破坏,攻击者需要“破解”密码和用户名哈希,然后才能破坏该帐户。这也意味着,如果用户名是经过哈希处理和加盐的电子邮件地址,它们将受到更多保护,不会被出售给垃圾邮件发送者。

4个回答

你看到上面那个显示你的用户名的东西了吗?如果用户名现在存储散列,他们不能这样做,可以吗?

一个词,可用性。

虽然特里说的是真的,但有时登录系统实际上是对用户名进行哈希处理(但没有加盐)。他们让您选择登录名和显示名。登录名存储为散列(没有加盐,因为您需要能够查找它)并且密码是加盐的。显示名称与您的登录名不同(因为这也应该保密)并在需要的地方显示。

即使攻击者看到您的姓名,他也无法将其附加到您的登录名中。虽然我说它可以加盐,但实际上没有必要这样做。最重要的部分只是保守秘密。如果数据库遭到破坏,如果攻击者想对您的其他帐户发起新的攻击,您的电子邮件地址或姓名等信息仍将在那里供攻击者使用。

通常用户名不被认为是安全的,它们是身份,而不是身份验证。最好不要透露哪些用户名是有效的,但如果碰巧发生冲突会更糟。您仍然可以通过查看所有匹配的用户名以获得匹配的密码哈希来解决此问题,但这有点混乱。

实际上,如果您在其他方面具有良好的密码安全性和登录尝试限制,那么完整的用户名列表对攻击者几乎没有实际价值。它的主要好处是网络钓鱼,但如果您的官方通信中有任何信息,那么这些信息就不能被散列,如果他们破坏了您的数据库,他们就会得到它。

此外,像特里所说的可用性。如果他们可以看到用户名,则更容易找到您的帐户。在大多数情况下,通过尝试保护标识符来证明它的合理性,您并没有获得足够的收益。

虽然其他人已经很好地指出,优势很少(如果有的话),但我会反对你声称没有任何缺点的说法。如果您只存储散列的用户名,那么搜索用户名很容易。如果你存储一个加盐的、散列的用户名,那么搜索就会变得有点问题。

假设如果我们构建一些包含用户名和(散列)密码的 SQL 表,并告诉 SQL 服务器索引用户名列,它将执行某种二进制搜索或其他一些魔法。我们可以有一个看起来像这样的表:

Username  |  Password
test      |  j9lnvqjAuhNJs

(这是老式的 unix crypt(3) 哈希,只是为了简单和简洁。)

如果您以明文形式存储用户名,则检索用户的(散列)密码是一个简单的 SQL 调用。假设您要验证输入用户名的用户的凭据test

SELECT password FROM users WHERE username='test`;

很简单。现在,如果我们以与密码相同的格式存储用户名,我们的表格最终看起来像这样:

Username       |  Password
M1CAtvzDdJDGU  |  j9lnvqjAuhNJs

现在当用户输入他们的用户名时test,你如何验证密码?二进制搜索在这里是没有用的,因为你甚至不知道你用来存储用户名的盐。相反,您需要遍历数据库中的每个用户名,crypt将给定的用户名与该用户名的盐值进行比较,并将其与存储的(散列)用户名进行比较以查看它是否匹配。你!

假设您采取了一些很好的预防措施并使用了一个不错的慢散列bcrypt而不是旧的 Unix crypt?双倍!

可以想象,存储加盐散列的用户名而不仅仅是纯文本存在一些严重的缺点。