小编典典

C# 中的哈希和盐密码

all

我刚刚浏览了 DavidHayden 的一篇关于Hashing User
Passwords
的文章。

真的,我无法得到他想要达到的目标。

这是他的代码:

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# 方法用于散列密码并添加盐?


阅读 67

收藏
2022-07-16

共1个答案

小编典典

实际上,这有点奇怪,使用字符串转换 - 成员资格提供程序将它们放入配置文件中。哈希和盐是二进制
blob,除非要将它们放入文本文件,否则无需将它们转换为字符串。

在我的《开始 ASP.NET 安全性》一书中,(哦,终于有了一个拉皮条的借口)我做了以下事情

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;
}

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

2022-07-16