重点加强。我做得对吗?

时间:2011-03-22 13:57:05

标签: c# security passwords cryptography

我正在使用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);

加强密钥(如第一个代码块所示)和加强哈希值(如第二个代码块所示)之间有什么区别?

散列密码时进行键拉伸的首选方法是什么?

2 个答案:

答案 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