一尘不染

C#中的哈希和盐密码

c#

我只是在阅读DavidHayden的有关散列用户密码的文章之一。

真的我无法理解他想要达到的目标。

这是他的代码:

private static string CreateSalt(int size)
{
    //Generate a cryptographic random number.
    RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
    byte[] buff = new byte[size];
    rng.GetBytes(buff);

    // Return a Base64 string representation of the random number.
    return Convert.ToBase64String(buff);
}

private static string CreatePasswordHash(string pwd, string salt)
{
    string saltAndPwd = String.Concat(pwd, salt);
    string hashedPwd =
        FormsAuthentication.HashPasswordForStoringInConfigFile(
        saltAndPwd, "sha1");
    return hashedPwd;
}

还有其他C#方法用于哈希密码并为其添加盐吗?


阅读 228

收藏
2020-05-19

共1个答案

一尘不染

实际上,对于字符串转换来说,这有点奇怪-
成员资格提供程序所做的就是将其放入配置文件中。哈希和盐是二进制Blob,除非要将它们放入文本文件,否则无需将它们转换为字符串。

在我的《Beginning ASP.NET
Security》
一书中(最后,借口是这本书的借口),我执行以下操作

static byte[] GenerateSaltedHash(byte[] plainText, byte[] salt)
{
  HashAlgorithm algorithm = new SHA256Managed();

  byte[] plainTextWithSaltBytes = 
    new byte[plainText.Length + salt.Length];

  for (int i = 0; i < plainText.Length; i++)
  {
    plainTextWithSaltBytes[i] = plainText[i];
  }
  for (int i = 0; i < salt.Length; i++)
  {
    plainTextWithSaltBytes[plainText.Length + i] = salt[i];
  }

  return algorithm.ComputeHash(plainTextWithSaltBytes);            
}

盐的生成就是这个问题的例子。您可以使用将文本转换为字节数组Encoding.UTF8.GetBytes(string)。如果必须将哈希转换为字符串表示形式,则可以使用Convert.ToBase64String并将Convert.FromBase64String其转换回。

您应该注意,不能在字节数组上使用相等运算符,它会检查引用,因此您应该简单地遍历两个数组,检查每个字节,从而

public static bool CompareByteArrays(byte[] array1, byte[] array2)
{
  if (array1.Length != array2.Length)
  {
    return false;
  }

  for (int i = 0; i < array1.Length; i++)
  {
    if (array1[i] != array2[i])
    {
      return false;
    }
  }

  return true;
}

始终 为每个密码使用新的盐。盐不必保密,可以与哈希表本身一起存储。

2020-05-19