Соль (криптография)

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

Простейшая схема подмешивания соли при хэшировании паролей

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

Пример использования

править

Пусть пароли хешируются по алгоритму MD5 и хранятся в виде хэш-значений в базе данных. В случае кражи базы исходные пароли могут быть восстановлены с помощью заранее подготовленных радужных таблиц, так как зачастую пользователи используют ненадёжные, легко подбираемые по словарям пароли[1]. Если же пароль «посолить», то есть, при вычислении хэш-значений присоединить к входным данным строку из нескольких случайных символов, которые будут являться значением соли, то результирующие значения не будут совпадать с распространёнными словарями хэш-значений. Знание соли позволяет сгенерировать новые словари для перебора, поэтому значение соли должно храниться в тайне. Для соли верны те же рекомендации к сложности, что и для сложности пароля, то есть, значение соли должно обладать хорошей энтропией и длиной[2].

Пример создания хеша с использованием статичной соли на языке PHP по принципу конкатенации (соединения) с входными данными:

  $password1 = '12345';
  $password2 = '67890'; 
  $salt = 'sflpr9fhi2'; // «Соль»
  $password1_saltedHash = md5($password1 . $salt); // Соединяем входную строку с «солью» и пропускаем через хэш-функцию md5()
  $password2_saltedHash = md5($password2 . $salt);

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

Динамическая соль

править

Существуют схемы формирования (генерации) динамической соли, при которых значения соли генерируются для каждого входного значения индивидуально (персонально), что затрудняет составление словарей перебора и скрывает факт наличия одинаковых паролей у разных пользователей. Также эффективность схемы увеличивается, если используется нетривиальное подмешивание по некоторому алгоритму. Например, соль можно не просто приписывать к концу пароля, а «подмешивать» в определённые промежутки пароля. К тому же хэш можно вычислять циклически, подмешивая соль частями с некоторыми изменениями[3], зависящими от номера итерации хэширования.

 
Существуют стандарты для использования соли в хешировании. На данной схеме изображён стандарт PBKDF, который на данный момент имеет вторую версию

Один из известных стандартов PBKDF2 описывает подмешивание соли в несколько итераций.

Пример хранения одинаковых паролей от разных пользователей при условии персонально сгенерированной (динамической) соли
Имя пользователя Пароль md5 (пароль) Соль Пароль+соль md5 (пароль+соль)
user1 qwerty123 3fc0a7acf087f549ac2b266baf94b8b1 5hr8Uh32Hr qwerty1235hr8Uh32Hr 1dfa98fc519fc0022e86014445d8b158
user2 qwerty123 3fc0a7acf087f549ac2b266baf94b8b1 Ju5yFy35Jk qwerty123Ju5yFy35Jk 269777fd3b1c37ef1cfc1e238213324f

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

Проблемы, связанные с солью и надёжностью паролей

править

Злоумышленник, несанкционированно получивший из базы данных системы авторизации сведения для авторизации, может использовать полученные сведения для авторизации от имени пользователей. Если пароли хранились в изначальном (открытом) виде, злоумышленник может использовать их для доступа к другим веб-сервисам (ресурсам), так как зачастую пользователи используют одинаковые пароли для разных веб-сервисов[4]. Использование динамической соли позволяет избежать компрометации аккаунтов пользователей на нескольких веб-сервисах.

При плохо продуманной системе применения соли её преимущества теряются.

Малая длина соли и низкая энтропия

 
Схема хранения соли в базе данных. При компрометации базы также компрометируется соль

Если соль имеет малую длину, злоумышленнику будет легко создать радужную таблицу, состоящую из всех возможных солей определённой длины, добавляемых к каждому вероятному паролю. К тому же использование соли с низкой энтропией увеличит вероятность успешного нахождения соли по словарю. Поэтому значение соли в идеале должно генерироваться с использованием ДСЧ[5]. Использование длинной соли с хорошей энтропией гарантирует, что радужная таблица для базы данных будет слишком большой и потребует для своей генерации и хранения значительных ресурсов злоумышленника[6].

Повторное использование соли для разных прообразов

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

Если используется одна фиксированная соль, то у пользователей с одинаковыми паролями будут одинаковые хэши. Это упрощает атаку, так как взлом одного хеша — взлом нескольких пользователей с одинаковыми паролями[7].

Преимущества использования соли в системах авторизации

править

Чтобы понять разницу между взломом одного пароля и их набором, рассмотрим файл паролей, содержащий сотни имён пользователей и хэшированных паролей. Без соли злоумышленник может вычислить хэш от некоторого значения (например, взятого из словаря), а затем проверить, встречается ли полученных хэш в файле. Вероятность совпадения, то есть, взлома одного из паролей, увеличивается с увеличением количества имеющихся в файле паролей. Если же используется (динамическая) соль (соль, имеющая как минимум несколько возможных значений для одного хэша), то злоумышленник должен вычислить хэш для каждой возможной пары «возможный пароль» и «соль», что увеличивает трудоёмкость перебора.

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

Использование соль защищает от злоумышленников, использующих хэш-таблицы и радужные таблицы, поскольку увеличивает длину и сложность пароля. Если в радужных таблицах нет паролей, соответствующих длине (например, 8-байтовый пароль и 12-байтовая соль, что по сути является 20-байтовым паролем) и сложности (сложная соль с высокой энтропией увеличивает сложность простых строго буквенно-цифровых паролей) солёного пароля, то пароль не будет найден.

Современная система теневых паролей, в которой хэши паролей и другие данные безопасности хранятся в непубличном файле, отчасти решает проблему несанкционированного доступа к файлу с хэшами. Проблемы остаются актуальными для многосерверных установок, использующих централизованные системы управления паролями для передачи паролей или хэшей паролей нескольким системам[8].

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

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

Соль в системах UNIX

править

В большинстве UNIX-систем в качестве односторонней функции используется функция crypt(3). Изначально функция для хеширования использовала алгоритм DES. При этом пароль был ограничен 8-ю символами (по 7 бит на символ, то есть, 7*8 = 56 бит), и использовалась 12-битная соль[9].

В 1994 году Пул-Хеннинг Кэмп на базе MD5 создал новый алгоритм хеширования паролей, который позволял использовать пароли любой длины, и использовал тысячу итераций MD5[10][11]. Результатом работы функции стала строка, содержащая метку алгоритма хеширования (версию), соль и хеш.

По тем временам задержка для вычисления такого хеша была достаточной для эффективного противостояния нахождению пароля полным перебором. Однако по мере роста вычислительных способностей время нахождения MD5 уменьшилось. Это привело к реализации для функции crypt вычислительно более сложных алгоритмов и возможности выбора количества итераций[12].

Сейчас функция поддерживает следующие алгоритмы хеширования: MD5, SHA-256, SHA-512, Blowfish (в некоторых дистрибутивах Linux, OpenBSD и некоторых других UNIX-подобных системах)[13]. Результатом работы функции является строка, содержащая имя алгоритма хеширования, соль, хеш и другие данные (например, количество раундов хеш-функции).

В 2012 году Пул-Хеннинг Кэмп призвал прекратить использование созданного им алгоритма md5crypt, как не обеспечивающего в современных условиях ощутимого увеличения времени вычисления хеша, а значит, и не защищающего от перебора[14].

В случае использования динамической соли, хранящейся в базе данных вместе с усиленным ей паролем, для дополнительной безопасности может использоваться дополнительная строка, называемая перцем[англ.][15]. Перец, аналогично с солью, добавляется к входным данным, однако при этом хранится отдельно. Чаще всего его сохраняют в конфигурационных файлах или переменных окружения, что дополнительно осложняет использование радужных таблиц[16].

См. также

править

Примечания

править
  1. Исследование на тему паролей. Security-Corp.org - ресурс посвященный вопросам информационной безопасности. Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  2. Какой пароль защитит от взлома, или энтропия на службе секретности. samag.ru. Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  3. «Соленое» хеширование паролей: делаем правильно. Интернет-технологии.ру. Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  4. Club.CNews.ru: 52% пользователей используют одинаковые пароли на разных сайтах. Club.CNews.ru. Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  5. Генераторы случайных чисел в криптографии. studopedia.net. Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  6. Скорость перебора паролей на CPU и GPU. bozza.ru. Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  7. Миллионы пользователей Microsoft используют повторяющиеся пароли. i2HARD. Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  8. Распределённое хранение парольных хэшей — «Хакер». Дата обращения: 14 декабря 2019. Архивировано 14 декабря 2019 года.
  9. Проект OpenNet: MAN crypt (3) Библиотечные вызовы (FreeBSD и Linux). Дата обращения: 24 июня 2012. Архивировано 26 июня 2012 года.
  10. FreeBSD CVS log for src/lib/libcrypt/crypt.c. Дата обращения: 9 июля 2012. Архивировано 12 июля 2013 года.
  11. Niels Provos, David Mazières. A Future-Adaptable Password Scheme. Paper - 1999 USENIX Annual Technical Conference, June 6-11, 1999, Monterey, California, USA (июнь 1999). Дата обращения: 9 июля 2012. Архивировано 9 августа 2012 года.
  12. Unix crypt with SHA-256/512. Дата обращения: 24 июня 2012. Архивировано 16 июля 2013 года.
  13. crypt(3) — Linux manual page. Дата обращения: 24 июня 2012. Архивировано 2 мая 2012 года.
  14. Md5crypt Password scrambler is no longer considered safe by author. Дата обращения: 9 июля 2012. Архивировано из оригинала 17 марта 2018 года.
  15. NIST Special Publication 800-63B (16 декабря 2022). — «"... verifiers SHOULD perform an additional iteration of a keyed hashing or encryption operation using a secret key known only to the verifier"». Дата обращения: 10 октября 2023.
  16. Webster, Craig Securing Passwords with Salt, Pepper and Rainbows. Barking Iguana (3 августа 2009). Дата обращения: 11 ноября 2020.

Литература

править