在散列像 hash(username_str + password_str) 这样的密码时,使用用户的用户名作为盐是个好主意吗?

信息安全 哈希
2021-08-21 18:29:40

我正在帮助我的朋友散列他的密码,我有一个问题 - 他应该使用一个秘密字符串作为散列盐还是让每个用户自己的散列盐更好?

考虑这三个哈希:

hash("secretKey777" + password);
hash("secretKey777" + username + password);
hash(username + password);

哪个最难破解,最安全?

我认为最好使用hash("secretKey777" + username + password);,因为每个用户不仅有“secretKey777”作为盐,还有自己的用户名。如果散列密码的代码泄露,不会同时对所有散列进行攻击——每个散列都有自己独特的盐。

3个回答

salt 的主要特征是它对于每个用户的密码散列应该是全局唯一的。它不需要保密,用户名肯定不会满足唯一性的要求。共享秘密字符串(用于所有用户)不是盐,而是胡椒,并且没有被证明可以为未加盐的密码增加任何安全性,因此不是一个可行的选择。

一种具有特别可能是全球唯一特性的结构是合理长度的随机数据。盐实际上不需要是随机的,但是为每个用户单独生成的随机值可以合理地保证我们具有所需的唯一性。

这个答案还有更多内容: 什么应该用作盐?

有人提到盐不必是秘密的,只是在所有应用程序中都是唯一的,并且用户名不符合该要求。

然后我的建议是使用您的域名和用户的用户名的组合作为盐:

“example.comsomeuser777” 这对用户和应用程序都是唯一的。

如果更改用户名,则要求用户输入密码。

他应该用一根秘密的绳子作为盐吗

不会。一种硬编码的侧宽盐确实可以防止预先计算的彩虹表攻击,但现在这些并不是真正的主要问题。对每个散列密码使用随机盐的主要优点是攻击者在暴力破解时必须使用每个盐对每个密码进行散列,而不是只散列一次并检查所有密码。因此,它将攻击速度减慢了与用户数量相等的因子。

每个用户不仅有“secretKey777”作为盐,还有自己的用户名

不要将用户名用作哈希。它不会真正影响安全[*],但它确实对可用性和可维护性有影响。如果用户想要更改他们的用户名怎么办?用你的方法这是不可能的。

[*] 除了@Xander提出的观点。这是一个影响,但它是非常低的。

那么正确的做法是什么?

hash(password+ generateRandomSalt());

并将盐存储在数据库中用户名和密码旁边。您还可以使用为您管理所有这些的库(例如,如果您使用 PHP,则password_hash使用 bcrypt 并为您管理盐)。