我工作的公司签订了一份大型订单处理系统的支持合同。作为初始系统审核的一部分,我注意到存储在数据库中的密码实际上是密码的哈希码。
本质上:
string pwd = "some pasword";
string securePwd = pwd.GetHashCode();
我的问题是,这有多安全?
我对此感到不舒服,但我对 GetHashCode 的工作原理知之甚少。我更喜欢使用像 MD5 哈希这样的东西,但如果我在浪费时间,那么我不会打扰。
我工作的公司签订了一份大型订单处理系统的支持合同。作为初始系统审核的一部分,我注意到存储在数据库中的密码实际上是密码的哈希码。
本质上:
string pwd = "some pasword";
string securePwd = pwd.GetHashCode();
我的问题是,这有多安全?
我对此感到不舒服,但我对 GetHashCode 的工作原理知之甚少。我更喜欢使用像 MD5 哈希这样的东西,但如果我在浪费时间,那么我不会打扰。
它不仅不安全,而且可能会发生变化:
http://netrsc.blogspot.com/2008/08/getashcode-differs-on-systems.html
GetHashValue 为给定输入返回的值在过去发生了变化。
无法保证在应用程序的不同执行之间它甚至是相同的。
GetHashCode
返回一个 32 位整数作为哈希值。考虑到生日悖论,由于碰撞概率相对较高,它不是一个足够长的哈希值,即使它被明确设计为抗碰撞,但事实并非如此。
您应该选择 SHA256 或其他旨在处理此类任务的加密安全哈希函数。
要存储密码,仅使用简单的哈希函数是不够的。您应该为每个用户添加一些随机的“盐”并迭代足够多的时间,这样蛮力的计算成本就会很高。因此,您应该使用具有大量迭代的bcrypt、 scrypt 、PBKDF2 之类的东西。
我建议改用BCrypt。正如其他人已经说过的那样,使用 GetHashCode 作为密码并不是一个好主意。
GetHashCode 绝对不是为了以这种方式使用而设计的,因为实现不保证不同对象的不同哈希返回。这意味着潜在的多个密码可能会产生相同的哈希值。也不保证在不同版本的 .NET 框架上返回相同的哈希值,这意味着升级可能会为相同的字符串生成不同的哈希值,从而使您的密码无法使用。
建议您在推送时使用加盐哈希甚至 MD5。您可以轻松地将其切换到Security.Cryptography命名空间中的内容。
正如其他人所说,GetHashCode 不是为您想要做的事情而设计的。有一篇关于如何安全处理用户密码的非常好的文章。
总结这篇文章,您需要使用相对较慢的自适应散列方案,例如bcrypt,或者斯坦福安全远程密码协议。我建议前者。当然,您还应该使用盐。