我对哈希密码和盐值有个想法。由于我是哈希和加密的新手,所以我想将其发布给您。为每个用户帐户生成唯一的盐,然后将盐和哈希值存储在数据库中,是否更安全?或者,是否安全地存储一个盐值,并在每次对密码进行哈希处理时重复使用该盐值?

例如,
用户将使用密码:

"secret"

我的代码将产生以下盐值:
"d1d0e3d4b3d1ed1598a4e77bb614750a2a175e"

然后对结果进行哈希处理以获得:
"e8187dcbe8e2eabd4675f3a345fe21c98affb
 5544a9278461535cb67265b6fe09a11dbef572
 ce3a4a8f2275839927625cf0bc7bc46fc45d51
 12d7c0713bb4a3"

创建用户帐户后,哈希结果和盐将存储在用户配置文件中的数据库中。然后,每次用户登录时,将生成一个新的盐,密码和盐将重新加密并存储在数据库中。

有什么想法吗?就像我说的那样,这是对我的想法的理智检查。

最佳答案

在我看来,为每个用户存储唯一的盐是一个好主意。除非您需要消耗CPU周期,否则每次用户登录时重新生成盐/哈希组合都是没有意义的。我建议使用类似 Rfc2898DeriveBytes 类的东西来生成安全的salt/hash组合:

从密码生成哈希的简单示例:

string password = GetPasswordFromInput();

using (var deriveBytes = new Rfc2898DeriveBytes(password, 32))  // 32-byte salt
{
    byte[] salt = deriveBytes.Salt;
    byte[] hash = deriveBytes.GetBytes(32);  // 32-byte hash
    SaveToDatabase(salt, hash);
}

并进行相应的密码检查:
string password = GetPasswordFromInput();
byte[] salt = GetSaltFromDatabase();
byte[] hash = GetHashFromDatabase();

using (var deriveBytes = new Rfc2898DeriveBytes(password, salt))
{
    if (deriveBytes.GetBytes(32).SequenceEqual(hash))
        Console.WriteLine("Password matches");
    else
        throw new Exception("Bad password");
}

10-01 00:55
查看更多