简体   繁体   English

使用相同的用户名密码哈希不同的盐

[英]Password hashing different salt with same username

We introduced password encryption to our site. 我们在网站上引入了密码加密。 The salt is calculated as shown below: 盐计算如下:

Rfc2898DeriveBytes hasher = new Rfc2898DeriveBytes(Username.ToLowerInvariant(),
           System.Text.Encoding.Default.GetBytes("Wn.,G38uI{~6y8G-FA4);UD~7u75%6"), 10000);
string salt = Convert.ToBase64String(hasher.GetBytes(25));

For most usernames the salt is always the same. 对于大多数用户名,盐总是相同的。 But for some usernames it changes at every call. 但是对于某些用户名,它在每次调用时都会更改。 Can someone tell me what we are doing wrong? 有人可以告诉我我们做错了什么吗?

Assuming you're using RFC2898DeriveBytes to hash the password itself as well, then @CodesInChaos is correct, what you're doing wrong is: 假设您也使用RFC2898DeriveBytes来对密码本身进行哈希处理,那么@CodesInChaos是正确的,您在做错的是:


byte[] salt1 = new byte[8];
using (RNGCryptoServiceProvider rngCsp = new RNGCryptoServiceProvider())
  {
  // Fill the array with a random value.
  rngCsp.GetBytes(salt1);
  }

  • The salt should then be stored in the clear in your database alongside the password hash and iteration count (so you can change it), and probably a version code too (so you can change it again, ie your current calculated salt method is version 1, and the random salt is version 2). 然后,应将盐与密码哈希和迭代计数(以便您可以更改)以及可能的版本代码(也可以再次更改)一起存储在数据库的明文中,以便您可以再次更改它,即您当前计算的盐方法为版本1 ,而随机盐为版本2)。

    • Spending 20,000 iterations of PBKDF2 on the salt, rather than spending it on the actual password hash! 在salt上花费20,000次PBKDF2迭代,而不是花在实际的密码哈希上!
  • 10,000 iterations for the first 20 bytes, since RFC2898DeriveBytes is PBKDF2-HMAC-SHA-1, and SHA-1 has a native 20 byte output 前20个字节10,000次迭代,因为RFC2898DeriveBytes为PBKDF2-HMAC-SHA-1,并且SHA-1具有本机20字节输出
  • 10,000 more iteration for the next 20 bytes, which is then truncated to only the 5 you need to get to a 25 byte output. 接下来的20个字节将再进行10,000次迭代,然后将其截断为仅25个字节输出所需的5个字节。
  • This is a weakness, as the defender has to spend the time on the salt on every login, whether it's spent on the salt, or the password hashing. 这是一个弱点,因为防御者必须在每次登录时花一些时间在盐上,无论是花在盐上还是密码哈希上。 The attacker has to spent that time once for each username, and then they are going to store the results and try _illions (where _ is very large) of password guesses. 攻击者必须为每个用户名花费一次时间,然后他们将存储结果并尝试_illions(其中_非常大)密码猜测。
    • Thus, the attacker has a greater than normal marginal advantage because they can precalculate the salt, while you have to calculate it on the fly. 因此,攻击者具有比通常更大的边际优势,因为他们可以预先计算盐,而您必须即时计算。

If you aren't using RFC2898DeriveBytes, another PBKDF2 implementation, BCrypt, or SCrypt to do the actual password hashing, then that's what you're doing wrong. 如果您没有使用RFC2898DeriveBytes,另一个PBKDF2实现,BCrypt或SCrypt来进行实际的密码哈希处理,那么就是您在做的错误。

Trimming the username some, but not all of the time is entirely incidential; 偶尔(但并非所有)修剪用户名完全是偶然的; just make sure not to trim passwords before they're hashed. 只要确保在散列密码之前不要修剪密码即可。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM