Ключ Усиление.Я делаю это правильно? - PullRequest
5 голосов
/ 22 марта 2011

Я пишу класс для хеш-паролей, который реализует 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-м блоке кода)?

Каков предпочтительный метод растягивания ключа при хешировании паролей?

Ответы [ 2 ]

4 голосов
/ 22 марта 2011

Если вы не крипто-гуру, просто придерживайтесь Rfc2898DeriveBytes, который, скорее всего, правильно реализован. Не поддавайтесь искушению взломать индивидуальное решение, которое нарушит безопасность вашей системы.

Нет причин хэшировать выходные данные Rfc2898DeriveBytes.

Непосредственно используйте GetBytes (), он был разработан для этого.

Какова цель вашего растяжения ключа? Шифр или хеш пароля? Для хэша пароля вы, вероятно, захотите использовать другой алгоритм.

1 голос
/ 03 июля 2013

Это довольно старый, но я сталкивался с этим, когда гуглял по тому же вопросу, и решение действительно заключается в том, чтобы придерживаться вывода Rfc2898DeriveBytes.

Rfc2898DeriveBytes - это реализация .NET PBKDF2. Требуется ваш пароль, соль и количество итераций. Это уже целая реализация, и нет необходимости перефразировать результат с помощью другого алгоритма хеширования.

На самом деле настоятельно рекомендуется не создавать собственную реализацию вокруг этого, так как вы можете нарушить безопасность, как уже упоминали другие люди.

Вот что делает https://openid.stackexchange.com, как вы можете видеть здесь: https://code.google.com/p/stackid/source/browse/OpenIdProvider/Current.cs#1135

...