PasswordDeriveBytes против Rfc2898DeriveBytes, устарел, но намного быстрее - PullRequest
17 голосов
/ 31 августа 2009

Я работаю над функциональностью шифрования, основанной на классах, унаследованных от SymmetricAlgorithm, таких как TripleDes, DES и т. Д.

По сути, для моего класса алгоритмов есть два варианта генерации согласованного ключа и IV: PasswordDeriveBytes и Rfc2898DeriveBytes, оба наследуют от абстрактного класса DeriveBytes.

Метод PasswordDeriveBytes.GetBytes() помечен как устаревший в .NET Framework, тогда как рекомендуется Rfc2898DeriveBytes.GetBytes (), поскольку он соответствует стандарту PBKDF2. Однако, согласно моему тестированию, вызов одного и того же метода GetBytes() в классе Rfc2898DeriveBytes почти в 15 раз медленнее, чем в классе PasswordDeriveBytes, что приводит к неожиданному использованию процессора (всегда выше 50%).

Вот некоторые данные тестирования:

  • Итерации: 100
  • Тип алгоритма: DES
  • Оригинальный текст: «Я тестовый ключ, зашифруйте меня, пожалуйста»
  • Время:
    • PasswordDeriveBytes: 99ms
    • Rfc2898DeriveBytes: 1373 мс

Исходя из результатов тестирования, плохая производительность Rfc2898DeriveBytes неприемлема в производственной среде.

Кто-нибудь замечал эту проблему раньше? Любое решение, которое я все еще могу использовать стандартное без ущерба для производительности? Есть ли риск использовать устаревший метод (может быть удален в будущей версии)?

Спасибо, ребята!

Edit:

Возможно, я обнаружил, в чем проблема ... Число итераций по умолчанию для PasswordDeriveBytes равно 100, а для Rfc2898DeriveBytes - 1000. После того, как я изменил их на то же число, что и 1000, выполнение Rfc2898DeriveBytes - только двойное время.

Ответы [ 3 ]

26 голосов
/ 31 августа 2009

Они не одно и то же.

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

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

Эти две функции несовместимы, и PasswordDeriveBytes не так безопасен.

10 голосов
/ 01 февраля 2012

Я думаю, что вы упускаете точку производных байтов. Это должно быть медленно. Он намеренно использует медленный алгоритм, который нельзя ускорить с помощью хитрого трюка. Типичный параметр «число итераций» должен находиться в диапазоне 2 ^ 16-2 ^ 20 и вводить задержку 0,1-0,5 секунды между вводом пароля пользователем и генерацией ключа. Намерение состоит в том, чтобы защитить от слабых паролей, выбранных «ленивыми невежественными пользователями», и замедлить поиск методом перебора.

10 голосов
/ 31 августа 2009

В этом посте рассказывается о различиях между ними: http://blogs.msdn.com/shawnfa/archive/2004/04/14/generating-a-key-from-a-password.aspx

...