.NET: разница между PasswordDeriveBytes и Rfc2898DeriveBytes - PullRequest
11 голосов
/ 17 августа 2011

Я пытаюсь понять какой-то C # -код, который мне вручают, который занимается криптографией и специально использует PasswordDeriveBytes из System.Security.Cryptography.

В .NET документах , он говорит, что PasswordDeriveBytes использует «расширение алгоритма PBKDF1», которое позже в документе указано как «стандарт PKCS # 5 v2.0», то есть PBKDF2 (насколько я могу судить).Тем не менее, везде в сети, которую я нашел (в том числе здесь, на Stack Exchange), все говорят: «используйте Rfc2898DeriveBytes, потому что Password * устарел и использует PBKDF1».Но единственная разница в документах на msdn.microsoft.com , похоже, заключается в том, что Rfc * -версия конкретно упоминает PBKDF2, где Password * говорит «расширение PBKDF1» и «PKCS # 5 v 2.0».

Итак, кто-нибудь может мне сказать, в чем разница между двумя классами (если есть) и почему я должен использовать один, а не другой для получения ключа пароля PBKDF2?

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

Ответы [ 4 ]

2 голосов
/ 12 июня 2017

Если вы создаете экземпляр PasswordDeriveBytes и делаете один вызов метода GetBytes, передавая значение, которое меньше выходного размера базового алгоритма дайджеста, вы получаете значение из PBKDF1 алгоритм.

Если вы делаете два вызова GetBytes для одного и того же объекта, вы можете столкнуться с ошибкой подсчета в реализации.

PBKDF1 описывается только для вывода до размера хеш-алгоритма (например, 20 байтов для SHA-1), но класс PasswordDeriveBytes создал формулу для поддержки до 1000 раз превышающего размер вывода хеша.Поэтому большое значение, создаваемое этим классом, может быть нелегко получить на другой платформе.


Если вы создадите экземпляр Rfc2898DeriveBytes, вы получите потоковую реализацию алгоритма PBKDF2 .Наиболее очевидное отличие PBKDF2 от PBKDF1 состоит в том, что PBKDF2 позволяет генерировать произвольный объем данных (ограничение составляет (2^32-1)*hashOutputSize; или для SHA-1 85 899 345 900 байт).PBKDF2 также использует более сложную конструкцию (в частности, HMAC поверх прямого дайджеста), чтобы затруднить восстановление входного пароля из выходного значения.

«Потоковая» реализация в том, что конкатенация GetBytes(5)и GetBytes(3) совпадает с GetBytes(8).В отличие от PasswordDeriveBytes, это правильно работает в Rfc2898DeriveBytes.


PBKDF1 изначально был создан для генерации ключей DES, опубликованных в PKCS # 5 v1.5 в 1993 году. PBKDF2 был опубликован в PKCS# 5 v2.0 (который был переиздан как RFC2898 ) в 1999 году. Скользящая колода, которую можно найти по адресу ftp: //ftp.rsasecurity.com/pub/pkcs/pkcs-5v2/pkcs5v2-0.pdf (но, похоже, возникают проблемы, поэтому ftp: //ftp.dfn-cert.de/pub/pca/docs/PKCS/ftp.rsa.com/99workshop/pkcs5_v2.0.ppt может понадобиться) дополнительно суммирует различия.(Слайд-колода была написана RSA Security, создателями PBKDF1 и PBKDF2, и они - люди, которые рекомендуют PBKDF2 вместо PBKDF1).

2 голосов
/ 30 января 2015

Я думаю, что отличный ответ на этот вопрос будет найден здесь:

C # PasswordDeriveBytes Confusion

Но для суммирования:

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

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

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

1 голос
/ 17 августа 2011

Вот блог, подробно описывающий различия:

http://blogs.msdn.com/b/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx

PBKDF2 может использоваться для генерации ключей любой длины, что очень полезно для шифрования на основе пароля (оно может генерировать ключи любой длины в соответствии с требованиями симметричного шифра), но означает меньше для безопасного хранения пароля , Он также применяет соль с использованием HMAC вместо конкатенации, как PBKDF1, которая обладает лучшими защитными свойствами в случае слабых солей.

0 голосов
/ 17 августа 2011

PKCS # 5 v2.0 определяет как PBKDF1, так и PBKDF2, первый по причинам обратной совместимости, а также рекомендует использовать PBKDF2 для новых приложений.Я понятия не имею, почему последний лучше первого, но два класса .NET, похоже, используют разные, но совместимые алгоритмы.(Возможно, потому что обменивается только полученный ключ, а не входы + KDF.)

...