PasswordDeriveBytes против Rfc2898DeriveBytes, устарел, но намного быстрее

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

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

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

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

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

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

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

Спасибо, парни!

Редактировать:

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

3 ответа

Решение

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

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

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

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

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

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

Другие вопросы по тегам