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