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 секунды между вводом пароля пользователем и генерацией ключа. Намерение состоит в том, чтобы защитить от слабых паролей, выбранных "ленивыми невежественными пользователями", и замедлить поиск методом перебора.