Обзор

Главное требование к любому шифрованию - наличие хорошего ключа.

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

Ключи должны иметь минимальную длину, которая зависит от алгоритма шифрования. Для шифрования AES + CBC требуется минимальная длина 16 байтов (128 бит), AES + GCM может работать с 12 байтами, но рекомендуется 16 байтов.

Все идет нормально. Мы хотим что-то зашифровать, мы просто генерируем случайный ключ с помощью безопасного генератора случайных чисел и готово. При взаимодействии программного обеспечения с программным обеспечением это может работать, и существует несколько схем безопасного обмена ключами¹²; Diffy-Hellman¹³ используется, например, в TLS. К сожалению, выделение шифрования начинается с ввода пользователем в качестве «паролей», которые затем используются в качестве ключей для шифрования, и, imho, это очень плохая идея, но что вы можете сделать?

Пароли не являются хорошими ключами шифрования¹⁵, и их «легко» угадать с помощью:

  • Атаки грубой силой (угадывание)
  • Радужные таблицы¹⁶ (угадывание с предварительно вычисленными хеш-значениями)

Чтобы использовать пароли в шифровании, нам нужно применить так называемую «функцию получения ключа» ¹ или KDF² (например, argon²¹⁷, scrypt¹⁸ или bcrypt¹⁹), а с хорошим KDF использовать случайную соль.

KDF дают нам следующее:

  • Они гарантируют, что у нас есть ключ шифрования длиной N, неотличимый от случайных данных. Длина обычно составляет 16, 32 или 64 байта (128, 256, 512 бит).
  • Они усложняют задачу, если бы не атаки грубой силы, поскольку их вычисление требовало больших вычислительных затрат, то есть медленных, и, как следствие, делало угадывание грубой силы невозможным.

Использование уникальной случайной соли дает нам:

Предупреждение:

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

Не храните хеш, если вы используете его для шифрования (я повторяюсь :)), лучше храните хеш, зашифрованный с помощью самого хеша.

Более пристальный взгляд на атаки методом грубой силы

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

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

Для «времени генерации хеша» у нас есть KDF. Они спроектированы так, чтобы быть медленными, а некоторые, например, argon²¹⁷, спроектированы так, чтобы занимать разумный объем памяти, поэтому выполнение вычислений на графических процессорах невозможно.

Аргон2

Argon2 (на момент написания этой статьи) считался лучшим KDF для использования для получения ключа пароля.

Argon²¹⁷ доступен в трех режимах: Argon2d, Argon2i и Argon2id.

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

Эталонная реализация²² находится на C, с привязками для многих языков.

Хеши не использовать

Не используйте md⁵²¹.

Это небезопасно использовать в чем-либо, связанном с безопасностью / криптографией. Единственное использование, которое у него теперь есть, - это вычисление контрольной суммы для операций, которые не чувствительны к безопасности.

К сожалению, есть много блогов, в примерах которых все еще есть md5. И что еще хуже, многие компании, многие хорошие программисты используют md5, когда им не следует (у меня нет ссылок на это).

Слабые ключи

Наконец, у нас есть слабые ключи. Слабые ключи не имеют ничего общего с паролями или тем, как они обрабатываются с помощью KDF.

Это криптографически безопасные сгенерированные ключи, которые делают алгоритм шифрования уязвимым для взлома⁷. Список алгоритмов шифрования со слабыми ключами см. В [6].

Хотя в целом AES не имеет слабых ключей, для режима GCM AES + GCM опубликовано несколько статей о слабых ключах, см .: [10] [11] [12]. Большая часть имеющихся на сегодняшний день материалов предполагает, что такие атаки либо маловероятны, либо крайне маловероятны, но риск все же существует. Добавьте к этому то, что при неправильном использовании GCM с фиксированной солью / iv результат будет катастрофическим²³.

ИМХО: я бы использовал GCM для всего, что имеет «недолговечные» ключи. Для таких вещей, как шифрование дисков, где ключи и шифры живут дольше, я бы использовал AES + CBC.

Соли

Соли²⁰ являются общедоступными, и они могут быть общедоступными⁴. Обычно соль хранится под вашим паролем. По их названию и определению, если бы они не были публичными, их бы называли Pepper²⁴.

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

Забрать:

  • Соли должны генерироваться криптографически безопасным генератором случайных чисел.
  • Соли должны быть уникальными для каждого хэша и каждой операции шифрования.
  • Соли бытовые.

Длина пароля

Здесь есть что сказать, и он заслуживает отдельного блога.

Недостаточно просто использовать достойный алгоритм хеширования и случайную уникальную соль.

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

Атакующему достаточно лишь однажды повезти.

Эта статья представляет собой очень интересное чтение о длине паролей и скорости офлайн-атак.

Вывод вот такой:

  • Пароли должны состоять из 12 или более символов.
  • Некоторые люди предлагают передать фразы.

Резюме

  • Используйте AES для шифрования.
  • Используйте случайные соли для хэшей паролей. Само по себе хеширование небезопасно, и повторное использование соли тоже небезопасно.
  • В идеале используйте KDF: argon2id²².
  • Убедитесь, что пароли состоят не менее чем из 12 символов.

использованная литература

Первоначально опубликовано на https://docs.pkhub.io.