Our Blog

Хеширование паролей

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

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

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

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

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

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

Перец (его еще называют локальной солью) — это глобальная строка, которая дописывается ко всем паролям. То есть ко всем паролям помимо уникальной для каждого пароля соли дописывавается одинаковый для всех перец. Он секретен (в отличии от соли), из этого следует, что получив базу, узнать пароли становится невозможно. Перец спасает от опасного и важного класса атак — компрометации БД без компрометации кода приложения. Данный вид атак довольно част, т.к. для дампа таблицы юзеров порой достаточно одного sql injection-а. А вот код приложения сдампить при sql-injection-е может и не получиться, особенно если он read-only.

Таким образом, теперь код выглядит как-то так:

$password = 'password';        //Сам пароль
$hash1 = md5($password);       //Хешируем первоначальный пароль
$salt = 'sflprt49fhi2';        //Генерируем случайный набор символов (соль)
$peper='j0i0s%kjj&&';
$hash2 = md5($hash1.$salt.$peper);  //Складываем хеш с солью и перцем, пропускаем через функцию md5()
Comments ( 0 )
    -->