使用 Rfc2898DeriveBytes 时,密码散列应包含多少字节?

How many bytes should a password hash be when using Rfc2898DeriveBytes?

我在下面有一个散列函数,128 字节散列对于密码来说是过大还是过小?

  public string HashPassword(string password)
  {
    Rfc2898DeriveBytes rfc = new(
      password,
      _salt,
      _iterations,
      _hashAlgorithmName
    );
    // is 128 bytes a good number?
    var hashedPasswordBytes = rfc.GetBytes(128);

    return Convert.ToBase64String(hashedPasswordBytes);
  }

这与您使用的_hashAlgorithmName的输出长度有关。例如,如果您使用 HMAC-SHA512,则输出长度为 512 位(64 字节)并且获得比 64 字节更多的字节有点矫枉过正。对于今天的标准来说,即使是 256 位的熵也足够了。

实际上,这就是为什么 ASP.NET Core Identity 包在使用 HMAC-SHA512 使用 Rfc2898DeriveBytes 散列密码时仅使用 32 个字节(256 位)。

供参考: https://github.com/dotnet/aspnetcore/blob/main/src/Identity/Extensions.Core/src/PasswordHasher.cs