c# - 实现哈希的最佳实践?

标签 c# .net sql-server c#-3.0

我需要实现散列(我不是指加密)来制作一些数据字段(密码或一些不需要以原始格式返回的细节,而只需要匹配在 db) 安全。你能给我建议实现散列的最佳实践吗?我将使用 C# 和 SQL Server,它将是一个网站。

最佳答案

好的,现在您已经说过要保护密码,您有一些选择。

.NET 框架有一些内置算法 - MD5、SHA1、SHA2。 MD5 和 SHA1 现在被认为是过时和危险的,而是坚持使用 SHA256。

例如(取 self 的书)

static byte[] GenerateSaltedHash(string password, byte[] salt)
{
  byte[] plainText = Encoding.UTF8.GetBytes(password);
  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];
  }

  byte[] hash = algorithm.ComputeHash(plainTextWithSaltBytes);            
}

现在盐可以阻止预先计算的哈希查找(哈希本身已经不够用了,人们已经预先计算了字典单词的哈希等等)。但是你怎么得到盐呢?好吧,它实际上是任何唯一值,通常是一组随机字节。

    public byte[] GenerateSalt(int length)
    {
        salt = new byte[length];

        // Strong runtime pseudo-random number generator, on Windows uses CryptAPI
        // on Unix /dev/urandom
        RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();

        random.GetNonZeroBytes(salt);

        return salt;
    }

所以你会先调用 GenerateSalt(32) 来获取盐(32 只是一个例子,如果你愿意的话可以更长。你需要把盐和密码一起存储——你不需要担心保护它完全没有。

最后您需要一个比较函数。当你想检查密码时,你会接受用户输入,为该用户获取盐,为提供的密码和存储的盐生成散列,然后进行比较。你会用类似的东西来做到这一点

[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
public static bool ConstantCompare(byte[] array1, byte[] array2)
{
    const byte Zero = 0;
    int maxLength = array1.Length > array2.Length ? array1.Length : array2.Length;
    bool wereEqual = array1.Length == array2.Length;

    byte[] paddedArray1 = new byte[maxLength];
    byte[] paddedArray2 = new byte[maxLength];
    for (int i = 0; i < maxLength; i++)
    {
        paddedArray1[i] = array1.Length > i ? array1[i] : Zero;
        paddedArray2[i] = array2.Length > i ? array2[i] : Zero;
    }
    bool compareResult = true;
    for (int i = 0; i < maxLength; i++)
    {
        compareResult = compareResult & paddedArray1[i] == paddedArray2[i];
    }
    return compareResult & wereEqual;
}

当然,我应该指出 ASP.NET 成员函数执行 salt 和 hash,因此它们应该是第一个调用点。如果其他人已经完成了工作,那么您自己动手就没有意义了。

关于c# - 实现哈希的最佳实践?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6338180/

上一篇:c# - NUnit属性

下一篇:C# ReceiveAsync 错误

相关文章:

c# - 将 Regex 结果传递给函数

c# - 带有转义变量的字符串连接

c# - n 个列表的笛卡尔积

sql-server - 使用标识列或搜索列上的索引加速 SQL 查询?

c# - IIS中如何配置连接池?

c# - 抽象出复合标识值以用于业务逻辑?

c# - 在两个不同的代码块使用相同的锁对象?

c# - 由于缺少未丢失的程序集引用,Visual Studio 拒绝构建项目

c# - 为什么 Entity Framework 实体是部分类?

sql-server - 使用内连接 sql 查询进行计数