Я пишу класс для хеш-паролей, который реализует Key Stretching с использованием класса System.Security.Cryptography.Rfc2898DeriveBytes для генерации ключей, используемых для вычисления значения хеш-функции.
Код, по сути, делает это:
// 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);
В чем разница между усилением ключа (как показано в 1-м блоке кода) и усилением хеша (как показано во 2-м блоке кода)?
Каков предпочтительный метод растягивания ключа при хешировании паролей?