我读过许多问题,建议将密码进行哈希处理并存储在数据库中。
当用户登录时,您使用所存储的信息哈希提供的密码。
我不明白的是这怎么可能起作用?因为两个字符串可能会哈希成相同的值 - 不太可能但绝对有可能。
有人可以帮助我吗?
编辑:有人能给出碰撞可能性的统计数据吗?
我读过许多问题,建议将密码进行哈希处理并存储在数据库中。
当用户登录时,您使用所存储的信息哈希提供的密码。
我不明白的是这怎么可能起作用?因为两个字符串可能会哈希成相同的值 - 不太可能但绝对有可能。
有人可以帮助我吗?
编辑:有人能给出碰撞可能性的统计数据吗?
您不应该以明文形式存储密码,因为您的数据库管理员不应该有访问客户密码的权限。
对密码进行哈希处理可以防止数据库管理员查看密码。
即使存在哈希碰撞的非常小的几率,这也不是问题,因为在锁定账户之前,这并不会显著增加某人尝试暴力破解客户密码的成功率。
附注:在哈希处理之前对密码进行盐值处理是一个好习惯,这样如果黑客以某种方式访问了密码表,则更难以使用彩虹表等手段进行暴力破解。
两个字符串可以哈希到相同的值 - 不太可能但绝对可能
是的,但如果哈希足够大并且质量良好,那么不必担心。用口语来说:每个应用程序用户同时被雷击的可能性不大,但绝对可能发生。你会为此而担心吗?
public static string ComputeHash(string plaintext)
{
HashAlgorithm mhash = new SHA1CryptoServiceProvider();
byte[] bytValue = Encoding.UTF8.GetBytes(plaintext);
byte[] bytHash = mhash.ComputeHash(bytValue);
mhash.Clear();
return Convert.ToBase64String(bytHash);
}
"MyAwesomePassword1"和"@@#ngt0n8$!!~~~09||{2`=&-[kla2%!Bq"可能会哈希成相同的值,这并不是一种安全漏洞。
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;
}
来源:http://davidhayden.com/blog/dave/archive/2004/02/16/157.aspx
尽管碰撞机会可能很小(取决于您的哈希算法),但这并不重要,对吧?
即使用户x和用户y具有相同的密码哈希,您也永远不会比较两个用户的密码以确定它们是否基于其哈希相同!因此,虽然“技术上”是碰撞哈希,但在这种情况下它并不会发生碰撞/干扰/影响。
是的,这是可能的,但对于良好的哈希函数来说不太可能。
举个例子:SHA1 是 160 位,这意味着要找到相同哈希值的两个字符串,您需要哈希大约 2^80 不同的字符串。即使使用所有最好的超级计算机,从未有人找到过哈希为相同 SHA1 值的两个字符串(虽然我预测很快会发生这种情况)。