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

Материал из Википедии — свободной энциклопедии
Перейти к: навигация, поиск

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

Пример использования[править | править исходный текст]

Например, вы шифруете и храните свои пароли в MD5. Если ваша база будет украдена — злоумышленник довольно просто восстановит большинство исходных паролей, используя заранее подготовленные радужные таблицы. Если же мы «посолим» пароль, то есть соединим строчку из 10-20 случайных символов с паролем и уже от этой строчки найдем MD5, — стандартные таблицы не будут работать, так как они не рассчитаны на поиск такой длинной строки.

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

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

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

Вот пример создания хеша с солью на PHP:

$password = 'password';        //Сам пароль
$hash1 = md5($password);       //Хешируем первоначальный пароль
$salt = 'sflprt49fhi2';        //Генерируем случайный набор символов (соль)
$hash2 = md5($hash1 . $salt);  //Складываем старый хеш с солью и пропускаем через функцию md5()

В данном примере соль является детерминированной строкой, в реальных проектах следует применять только случайные соли, сгенерированные каким-либо ГПСЧ.

Пример использования функции crypt на языке PHP:

// Создание хеша
$hash = crypt('password'); // crypt сама генерирует соль и хеширует, используя дефолтный алгоритм
// Если есть необходимость использовать определенный алгоритм, то нужно подготовить соль в формате crypt, а именно
// $<алгоритм>$<строка соли>$ или $<алгоритм>$<параметры хеширования>$<строка соли>$, если алгоритм требует дополнительные параметры
// Например: $1$xdtfsfre$ - MD5 алгоритм
 
// Проверка хеша
if (crypt($_REQUEST['password'], $hash) == $hash) { // crypt извлекает соль из хеша и хеширует входящий пароль с ее использованием
   // Пароль верен
}

Частые вопросы о соли для новичков[править | править исходный текст]

  • Зачем как-то шифровать пароли в базе? Если получили доступ к базе, то получили доступ ко всей системе!
  • Во-первых, не обязательно, что получили доступ ко всей системе. Например, утечка базы паролей через SQL-инъекцию вовсе не значит, что взломщик имеет доступ хоть к чему-нибудь, кроме этой базы.
  • Если ограничиться лишь обсуждением необходимости соли, то исходные пароли пользователей — это и есть та информация, которую мы защищаем. Пользователь может использовать тот же самый пароль для доступа к другой, пока не взломанной системе. Соль не спасет от подбора, например, администраторского пароля, однако существенно замедлит подбор паролей всех пользователей.
  • Не надежней ли использовать свой алгоритм хеширования? Тогда и никакая соль не нужна.
  • Свой алгоритм хеширования может быть прекрасной преградой для подбора паролей ровно до тех пор, пока он остается тайной. Так как этот алгоритм потребуется для проверки паролей, его реализация будет в коде вашей системы, а значит, может быть украдена. Как только алгоритм становится известен, по нему строятся радужные таблицы либо алгоритм реализуется в каком-либо переборщике паролей, после чего происходит быстрый подбор исходных паролей ваших пользователей.
  • Свой алгоритм хеширования, скорее всего, окажется криптографически нестойким. Разработка криптостойкого алгоритма — непростая задача, требующая усилий квалифицированных специалистов по криптографии.
  • Где хранить соль? Не опасно ли хранить ее в открытом виде? Можно ли поместить соль в код и ее использовать для всех паролей?
  • Все, что может быть украдено, будет украдено. Если вы уверены в защищенности кода, то свой алгоритм хеширования поможет лучше соли. Помните: соль не защищает один конкретный хеш от перебора, поэтому нет цели прятать соль — она хранится в открытом виде рядом с хешем. Задача соли — спасти набор украденных хешей, "удлиняя" пароль, а сделать она это может только в том случае, если у каждого хеша будет своя соль. Поэтому мы храним соль рядом с хешем и для каждого хеша генерируем свою уникальную последовательность символов соли.
  • Важная задача соли — в случае, если два пользователя поставили вдруг одинаковые пароли, сделать разными их хеши. Это скрывает факт совпадения паролей. Особенно это важно, если одному человеку разрешено иметь несколько аккаунтов.

Соль в системах Unix[править | править исходный текст]

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

В 1994 году Poul-Henning Kamp на базе MD5 создал новый алгоритм хеширования паролей, который позволял использовать пароли любой длины и использовал тысячу итераций MD5[2][3]. Результатом работы функции стала строка, содержащая метку алгоритма хеширования (версию), соль и собственно хеш.

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

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

В 2012 году Poul-Henning Kamp призвал полностью отказаться от созданного им алгоритма md5crypt, как не обеспечивающего в современных условиях ощутимого увеличения времени вычисления хеша, а значит, и не защищающего от полного перебора[6].

Литература[править | править исходный текст]

Примечания[править | править исходный текст]

  1. Проект OpenNet: MAN crypt (3) Библиотечные вызовы (FreeBSD и Linux)
  2. FreeBSD CVS log for src/lib/libcrypt/crypt.c
  3. Niels Provos, David Mazières. A Future-Adaptable Password Scheme. Paper - 1999 USENIX Annual Technical Conference, June 6-11, 1999, Monterey, California, USA (June 1999). Архивировано из первоисточника 9 августа 2012.
  4. Unix crypt with SHA-256/512
  5. crypt(3) - Linux manual page
  6. Md5crypt Password scrambler is no longer considered safe by author

См. также[править | править исходный текст]

Ссылки[править | править исходный текст]