我一直在阅读关于在数据库中保护用户密码的文章(https://crackstation.net/hashing-security.htm)。基本思想已经理解 - 生成随机盐,将其附加到密码上并对密码进行哈希处理。
这是我所做的(我没有在此处放置一些执行字符串转换的方法):
根据文章所述,这是安全的,但可以通过使用“密钥拉伸”来增加安全性。我理解的“密钥拉伸”是使用参数进行缓慢哈希处理,以使暴力破解密码更加困难。
所以这是我做的:
这是我所做的(我没有在此处放置一些执行字符串转换的方法):
RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
byte[] rndBytes = new byte[512];
randomNumberGenerator.GetBytes(rndBytes);
string salt = ToHexString(rndBytes);
var sha512Hasher = SHA512.Create();
string hashedPwd = ToHexString(sha512Hasher.ComputeHash(GetBytes(pwd + salt)))
根据文章所述,这是安全的,但可以通过使用“密钥拉伸”来增加安全性。我理解的“密钥拉伸”是使用参数进行缓慢哈希处理,以使暴力破解密码更加困难。
所以这是我做的:
RandomNumberGenerator randomNumberGenerator = RandomNumberGenerator.Create();
byte[] salt = new byte[512];
randomNumberGenerator.GetBytes(salt);
Rfc2898DeriveBytes k1 = new Rfc2898DeriveBytes(user.Password, salt, 1000);
byte[] hashBytes = k1.GetBytes(512);
string hash = ToHexString(hashBytes);
现在,这里有我的问题:
SHA512
和Rfc2898DeriveBytes
之间的区别是什么?哪一个更安全?- 我应该使用更多迭代次数但较小的盐吗?这样会使它更安全吗?
- 在1000次迭代中,它运行得非常快——它应该有多慢?半秒钟?一秒钟?这里有什么经验法则吗?
- 在数据库上,我应该将字节数组转换为字符串并存储字符串,还是应该将字节数组存储在二进制数据字段中?
编辑(另外的问题)
- 如果我对SHA512进行1000次重新哈希,它是否会提供相同的安全性?