我正在使用System.Security.Cryptography.Rfc2898DeriveBytes类编写一个用于哈希密码的类来实现Key Stretching,以生成用于计算哈希值的密钥。
代码基本上是这样做的:
// Higher iterations value results in better key strength
var db = new Rfc2898DeriveBytes(password + salt + secretKeyFromConfigFile,
saltAsBytes,
iterations);
byte[] hashKey = db.GetBytes(64); // 64 bytes is the recommended size for the HMACSHA512 class
var sha512 = new System.Security.Cryptography.HMACSHA512(hashKey);
byte[] hashInput = System.Text.Encoding.UTF8.GetBytes(password + salt + secretKeyFromConfigFile);
byte[] hash = sha512.ComputeHash(hashInput);
return System.Convert.ToBase64String(hash);
System.Security.Cryptography.Rfc2898DeriveBytes的文档表明它使用“...基于System.Security.Cryptography.HMACSHA1的伪随机数生成器”来派生密钥。
因为SHA512优于SHA1所以简单地应用SHA512散列函数会更好吗?
byte[] hash;
for (int i = 0; i < iterations; i++)
{
hash = sha512.ComputeHash(hash ?? hashInput);
}
return System.Convert.ToBase64String(hash);
加强密钥(如第一个代码块所示)和加强哈希值(如第二个代码块所示)之间有什么区别?
散列密码时进行键拉伸的首选方法是什么?
答案 0 :(得分:4)
除非你是加密大师,否则坚持Rfc2898DeriveBytes,这很可能是正确实现的。抵制将自定义解决方案黑客攻击破坏系统安全性的诱惑。
没有理由对Rfc2898DeriveBytes的输出进行哈希处理。
直接使用GetBytes(),它是专为该意图而设计的。
按键拉伸的目的是什么?密码或密码哈希?对于密码哈希,您可能希望使用不同的算法。
答案 1 :(得分:1)
这是相当古老的,但是当我在Google上搜索相同的问题并且解决方案确实坚持Rfc2898DeriveBytes的输出时,我遇到了这个问题。
Rfc2898DeriveBytes是PBKDF2的.NET实现。它需要您的密码,盐和迭代次数。这已经是整个实现,并且没有必要使用另一个散列算法重新结果。
事实上,强烈建议不要围绕此创建自己的实现,因为您可能会像其他人已经提到的那样破坏安全性。
这就是https://openid.stackexchange.com所做的,正如你在这里看到的: https://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135