С# PasswordDeriveBytes Confusion

У меня есть следующий код в С#

PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);
byte[] KeyBytes = DerivedPassword.GetBytes(32);

Я использую алгоритм хэширования "SHA1".

Согласно определению SHA1, он генерирует ключ 160 бит (20 байтов). Мой вопрос в том, как метод GetBytes получает 32 байта из DerivedPassword, какой алгоритм используется для метода GetBytes?

Ответ 1

Реализация Microsoft оригинального PKCS # 5 (aka PBKDF1) включает в себя небезопасные расширения для предоставления большего количества байтов, чем может предоставить хэш-функция (см. отчеты об ошибках здесь и здесь).

Даже если это не багги, вам следует избегать недокументированных, проприетарных расширений стандартов (или вы никогда не сможете расшифровать свои данные в будущем - по крайней мере, не за пределами Windows.)

Я сильно предлагает вам использовать новый Rfc2898DeriveBytes, который реализует PBKDF2 (PKCS # 5 v2), доступный с .NET 2.0.

Ответ 2

какой алгоритм используется для метода GetBytes?

Он использует алгоритм PBKDF1, который слегка изменен, чтобы разрешить произвольную длину ключа. Класс замены Rfc2898DeriveBytes использует PBKDF2.

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

Ответ 3

Функция деривации ключей использует функцию Key Stretching. (Не утруждайте себя поиском в Википедии, потому что текущая статья смущает концепцию с помощью Key Strengthening, что совершенно другое.)

Вытягивание клавиш обычно выполняется путем применения PRF (например, хеш-функции или шифра) в режиме CTR или путем повторения и конкатенации промежуточных выходов.

Например, если вы используете процедуру CTR, SHA-1 как PRF и хотите 32 байта псевдослучайного вывода, вы объединяете SHA1 (keymaterial, 0) с первыми 12 байтами SHA1 (keymaterial, 1).