盐和哈希,为什么不能使用用户名?

40

我必须承认,对于大多数与Web应用程序相关的高科技安全问题,我并不了解,但至少有一件事情我认为可以直接询问并得到具体答案。

以这个网站为例:http://www.15seconds.com/issue/000217.htm

它在页面下方展示了他们将盐值存储在表中,我理解使用盐的原理和数学原理,但我想知道:

他们为什么不只是使用用户名作为盐值,而不是生成一个盐值?

3个回答

43

盐的作用是要保持其独特性。盐的目的是为了防止攻击成本分摊,即攻击者尝试攻击两个经过哈希处理的密码所需成本小于攻击一个密码两倍的成本。

确保唯一性的一个解决方案是在足够宽广的空间中生成随机盐。因此,在两个不同的密码实例中获得相同的盐的概率足够小,以至于实际上不会发生。

用户名并足够独一无二:

  • 当用户更改密码时,用户名不会更改。攻击者看到旧的哈希密码和新的哈希密码可能会花费比攻击一个密码两倍的成本更少的成本来攻击这两个密码。
  • 在特定时间内,用户名在系统范围内是唯一的,而不是全球范围内唯一的。有许多名称为“bob”的用户(在Unix系统中,请考虑“root”)。使用用户名可能允许攻击者同时攻击多个系统。

盐的熵实际上并不重要,除非在随机生成设置中确保其唯一性。


我经常看到有关新旧密码的内容,但我不清楚攻击旧密码对人们有什么用处。我可以告诉你,我昨天使用的旧密码是“letmein”,但今天这并不能帮助你。 - Will Dean
8
在基于密码的加密中,比如保护Zip档案,这样说更有意义。此外,用户倾向于重复使用密码,因此旧密码经常也是未来的密码(或者是同一人在另一个系统中使用的密码)。 - Thomas Pornin
3
那么,我认为使用类似于 hash(domain + username + password) 的方式来使其在全局和本地都唯一是没有问题的。不过,有关旧密码和更改用户名的论点仍然有效。 - user2291758

30

因为用户名称的熵比随机盐低,所以它们比正确的盐更少地分散了您的哈希值。

不过那个页面上的例子也并不是非常惊人。我总是生成一个GUID并使用它。

我怀疑这在现实生活中对于安全性来说都微不足道,即使很小的每个用户的盐也会对安全性产生很大的影响,而盐变得更加复杂时,改进非常微小。


谢谢,这与我对该主题的原始想法相符。 - Lasse V. Karlsen
30
另一个考虑因素是:将用户名作为哈希的一部分,这样管理员更改用户的用户名将变得不可能,除非他们知道用户的密码或者重置密码。我曾在继承的一个系统中遇到过这个问题,该系统使用电子邮件地址作为用户名......哈希包括一个随机的盐字符串,但因为它还包括电子邮件地址,所以这会导致更改电子邮件的上述问题。 - Matt Browne
9
很好的观点!但有一个实际的想法:如果用户试图自行更改电子邮件,通常他应该输入密码以确认更改。您可以先验证密码(使用旧电子邮件/用户名),然后在单个事务中更改电子邮件地址,并从输入的密码计算新密码哈希值。并不是我建议使用用户名/电子邮件作为盐值,只是针对这个问题的一个想法。但显然,未经密码输入的电子邮件/用户名更改(例如管理员想要更改某人的电子邮件)仍将无法进行。 - Levite
1
当您首次构建系统时,不可能预测所有未来的需求之一可能是管理员更改用户名,即使最初似乎用户可以更改自己的用户名已足够。 - Matt Browne
1
更改密码哈希机制真的很麻烦,因为这意味着所有用户都必须更改他们的密码。 - Matt Browne

1
如何翻译:
Salt = CryptoHash( CryptoHash(SubmittedEmailOrUsername) . CryptoHash(SubmittedPasswd) ) ?

似乎这种方法有一个优点,即不需要存储盐,因为它可以动态计算,同时具有良好的熵(基于哈希而非明文),并提供与加密哈希相同长度的盐,例如128-512位?

其中一个问题是如果系统允许两个用户拥有相同的用户名和密码(但不会出现在电子邮件地址中),但这种方案还存在其他问题吗?


这是循环的:盐用于获取“CryptoHash(Passwd)”。 - Davis Herring
1
这并没有真正回答问题,问题是“为什么我们不使用用户名?”,而不是“我们可以做些什么来更好地使用用户名?” - Davis Herring
Davis,请您详细说明一下循环性吗?这里是注册+查找,看起来没问题吧?对于注册/新账户,新用户提交他们的电子邮件和密码 系统计算Salt = Hash(Hash(Email) . Hash(passwd)) 现在系统可以计算该电子邮件的StoredPassword = Hash(Salt . Email . Passwd)对于登录,用户输入电子邮件和密码 系统计算Salt = Hash(Hash(Email) . Hash(Passwd)) 系统查找电子邮件的StoredPassword 系统将StoredPassword与Hash(Salt . Email . Passwd)进行比较 - alienpup
对于格式化的歉意:(它不让我添加换行符(它说使用"<br/>",但似乎不在回复子集中),然后我的5分钟编辑时间过期了。现在正在阅读格式/评论帮助页面 - alienpup

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