使用GetHashCode来“保护”用户密码

3

我所在的公司接受了一份大型订单处理系统的支持合同。作为初始系统审核的一部分,我注意到存储在数据库中的密码实际上是密码的哈希码。

本质上:

string pwd = "some pasword";
string securePwd = pwd.GetHashCode();

我的问题是,这个方案有多安全?

我并不太放心,但是我对GetHashCode的工作原理了解不足。我更倾向于使用类似MD5哈希的东西,但如果这样做是浪费时间的话,我就不打算这么做了。

6个回答

5

5

+1 这个链接的示例表明,哈希值计算甚至可以在简单的 Windows 更新(修补 .NET 框架)之后发生变化。这意味着没有人可以再登录了。 - Wim Coenen

4

GetHashCode返回一个32位整数作为哈希值。考虑到生日悖论,由于碰撞的概率相对较高,即使它被明确设计成抗碰撞,也不是一个足够长的哈希值。

你应该选择SHA256或其他专门处理此类任务的加密安全哈希函数。

仅使用简单的哈希函数来存储密码是不够的。您应该为每个用户添加一些随机的“盐”,并迭代足够多次,以便计算上昂贵的暴力破解。因此,您应该使用像bcrypt,scrypt,PBKDF2这样的东西,并进行大量的迭代。


取决于您如何定义“破碎”。已知有计算值的方法会发生冲突(至少在MD5中我确定这种情况),但这并不意味着它们是无用的。即使是加盐的MD5,在大多数情况下也足以存储密码。它们的“破碎”属性对数字签名的影响更大。 - Mehrdad Afshari
哦,话说回来,我绝不建议使用MD5或SHA1。正如Mitch所说,应该选择SHA256或更高的哈希算法。我的评论重点在于“破解”的问题。在加密算法中,“破解”等同于“死亡”。但在哈希算法中,有一些灰色地带。 - Mehrdad Afshari
谢谢,这正是我所想的。我会尝试将系统迁移到SHA256。 - ilivewithian

2

我建议使用BCrypt代替。正如其他人已经指出的那样,使用GetHashCode作为密码并不是一个好主意。


1

GetHashCode 明显不是以这种方式使用的,因为其实现并未保证对于不同的对象会生成不同的哈希返回值。这意味着潜在地多个密码可能会产生相同的哈希值。同时,它也不能保证在不同版本的 .NET Framework 上返回相同的哈希值,这意味着升级后可能会为相同字符串产生不同的哈希值,使您的密码无法使用。

建议您使用加盐哈希或者至少 MD5,您可以很容易地切换到 Security.Cryptography 命名空间内的其他算法。


1

SRP与密码哈希的选择正交。它仍需要一个良好的慢哈希作为构建块。不幸的是,许多SRP实现使用快速哈希。 - CodesInChaos
你在回答中提供的处理用户密码安全的链接指向了某个ncctrust网站的主页。请问你能否修复一下? - saurabh64

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接