Подтвердить что ты не робот

Почему мне нужно использовать класс Rfc2898DeriveBytes (в .NET) вместо прямого использования пароля в качестве ключа или IV?

В чем разница между использованием Rfc2898DeriveBytes и просто использованием Encoding.ASCII.GetBytes(string object);?

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

Основная концепция, которую я смог понять, заключается в том, что вы можете преобразовать строковые пароли в байтовые массивы, которые должны использоваться, например, для симметричного класса шифрования, AesManaged. По RFC-классу вы можете использовать значения солей и пароль при создании вашего объекта rfc. Я предполагаю, что он более безопасен, но все же это необразованное предположение в лучшем случае! Кроме того, он позволяет вам возвращать байт-массивы определенного размера, ну что-то в этом роде.

Вот несколько примеров, чтобы показать вам, откуда я родом:

byte[] myPassinBytes = Encoding.ASCII.GetBytes("some password");

или

string password = "[email protected]%5w0r]>";
byte[] saltArray = Encoding.ASCII.GetBytes("this is my salt");
Rfc2898DeriveBytes rfcKey = new Rfc2898DeriveBytes(password, saltArray);

Теперь объект 'rfcKey' можно использовать для настройки свойств .Key или .IV на классе симметричного алгоритма шифрования.

т.

RijndaelManaged rj = new RijndaelManaged ();
rj.Key = rfcKey.Getbytes(rj.KeySize / 8); 
rj.IV = rfcKey.Getbytes(rj.Blocksize / 8);

'rj' должен быть готов к работе!

Запутанная часть... поэтому вместо использования объекта 'rfcKey' я могу не просто использовать мой 'myPassInBytes', чтобы помочь настроить мой объект 'rj'?

Я попытался сделать это в VS2008, и немедленный ответ НЕТ. Но вы, ребята, получили более образованный ответ о том, почему класс RFC используется по сравнению с другой альтернативой, о которой я упомянул выше?

4b9b3361

Ответ 1

Вы действительно не хотите использовать пароль пользователя напрямую в качестве крипто ключа, особенно с AES.

Rfc2898DeriveBytes - это реализация PBKDF2. То, что он делает, неоднократно хеширует пароль пользователя вместе с солью. Это имеет несколько преимуществ:

Во-первых, вы можете использовать пароли произвольного размера - AES поддерживает только определенные размеры ключей.

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

Множественные итерации (1000 по умолчанию) замедляют атаки на угадывание пароля. Подумайте о том, кто пытается угадать ваш ключ AES. Если вы просто использовали пароль, это было бы просто - просто попробуйте каждый возможный пароль в качестве ключа. С другой стороны, с PBKDF2, злоумышленник сначала должен выполнить 1000 итераций хэша для каждого угадывания пароля. Таким образом, хотя он немного замедляет пользователя, он оказывает непропорциональное воздействие на атакующего. (На самом деле это довольно часто, чтобы использовать гораздо более высокие значения итераций, обычно рекомендуется 10000).

Это также означает, что конечный выходной ключ равномерно распределен. Например, если вы использовали пароль, обычно 16 из 128 бит ключа были бы равны 0 (высокий бит ASCII). То, что прямо тут же делает keyearch 65536 раз проще, чем должно быть, даже игнорируя угадывание пароля.

Наконец, AES имеет специфические уязвимости со связанными ключевыми атаками. Связанные ключевые атаки возможны, когда злоумышленник знает некоторые данные, зашифрованные несколькими ключами, и между ними существует известная (или догадка) связь. Например, если вы зашифровали данные с ключом пароля "My AES key sucks" (16 байт, для AES-128) и с "MY AES KEY SUCKS", может быть возможна соответствующая ключевая атака. В настоящее время наиболее известные атаки фактически не позволяют взломать AES таким образом, но со временем они постепенно улучшались - на прошлой неделе была опубликована новая атака, которая разбивает 13 раундов (из 14 всего) AES-256, используя связанная ключевая атака. Было бы крайне неразумно полагаться на то, что такие атаки не улучшатся с течением времени.

Ответ 2

Короткий ответ: безопаснее. По той же причине также имеется специальный случайный генератор в пространстве имен System.Security.

Подробнее см. RFC2898

Я понимаю одну маленькую часть:

с Encoding.ASCII.GetBytes(), когда вы используете длинный пароль, вы будете использовать не более первых байтов rj.KeySize. Остальное игнорируется. И когда ваш пароль короче ключа, вам придется добавлять дополнения (и просто добавление последовательности из 0 увеличивает уязвимость).