请您告诉我以下是否是安全地散列密码以存储在数据库中的好方法:
public string CreateStrongHash(string textToHash) {
byte[] salt =System.Text.Encoding.ASCII.GetBytes("TeStSaLt");
Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(textToHash, salt, 1000);
var encryptor = SHA512.Create();
var hash = encryptor.ComputeHash(k1.GetBytes(16));
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++) {
sb.Append(hash[i].ToString("x2"));
}
return sb.ToString();
}
非常感谢提前。
答案 0 :(得分:7)
你使用PBKDF2-SHA1,这是不错的但不是很好。 Bcrypt好一点,scrypt更强。但是由于.net已经包含了内置的PBKDF2实现,这是一个可以接受的选择。
你最大的错误就是你没有得到盐。每个用户的盐应该是唯一的。简单地创建至少64位的随机值是标准做法。将它与哈希一起存储在数据库中。
如果您愿意,可以将盐分成两部分。一个与用户一起存储在数据库中,每个用户都不同,一个共享部分存储在其他地方。这样可以获得两者的优势。
我还建议使用比1000
更高的工作因子。找出可接受的性能,并进行相应调整。我不会低于10000,在某些情况下(磁盘加密)也可以接受一百万。
答案 1 :(得分:5)
可以改进。首先,您应该使用bcrypt代替。像SHA-512这样的传统哈希现在可以很容易地用GPU打破。问题是这些哈希是为速度而设计的,这与你想要的密码哈希相反。 Bcrypt是自适应散列算法的示例。它可以被配置为花费“很长”的时间(但仍然不会导致系统中的性能问题)使暴力行为变得困难。
您还希望为每个用户创建独特的盐。
有关如何安全地散列密码的详细信息,请参阅this question。