Наверняка тебе известно, что хорошая система контроля доступа, основанная на вводе и проверке правильности пароля, никогда и нигде не сохраняет пароли в открытом виде, а проверяет введенный пользователем пароль с использованием хеш-суммы этого пароля. А очень хорошие системы еще и добавляют к ним «соль» — случайную строку, которая для каждого пользователя уникальна. В этой статье мы на практике рассмотрим вопросы правильного хеширования паролей, руководствуясь при этом актуальными российскими методическими рекомендациями.

Как выглядят записи в базе данных пользователей «хороших систем контроля доступа»? Примерно так (здесь видны имя учетной записи пользователя, значение соли и значение хеша):

...
"Ivanov"  "QxLUF1bgIAdeQX" c9e209040c863f84a31e719795b25775239547
"Petrov"  "bv5PehSMfV11Cd" d1d3ec2e6f20fd420d50e2642992841d8338a3
"Sidorov" "YYLmfY6IehjZMQ" a49670c3c18b9e079b9cfaf51634f563dc88ed
...

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

Документ называется «Рекомендации по стандартизации Р 50.1.111—2016. Информационная технология. Криптографическая защита информации. Парольная защита ключевой информации». Он разработан техническим комитетом по стандартизации ТК 26 «Криптографическая защита информации» и представляет собой расширение международного стандарта PKCS #5 Version 2.0 (Public Key Cryptography Standart: Password-Based Cryptography Specification): в процедуру хеширования, описанную в PKCS #5, внесена возможность использовать алгоритм из ГОСТ Р 34.11—2012 (да-да, это тот самый «Стрибог» — похоже, нынче без него никуда).

В статье «Большой парольный коллайдер» показано, как находить пароль по хешу. Сможешь вскрыть первый хеш из примера (9e209...)?

Загрузка ... Загрузка ...
 

Общая схема и исходные данные

Основу алгоритма получения хеша составляет так называемая функция диверсификации PBKDF версии 2.0 (Password-Based Key Derivation Function). Данная функция реализуется путем применения псевдослучайной хеш-функции к строке, в нашем случае к паролю, вместе с солью, процесс повторяется большое число раз.

Общая схема выработки нужного нам хеша
Общая схема выработки нужного нам хеша

В качестве псевдослучайной хеш-функции мы будем использовать функцию вычисления аутентификационного кода сообщения HMAC_GOST3411 (Hash-based Message Authentication Code) на основе, как ты уже догадался, хеш-функции «Стрибог». Исходные данные для алгоритма:

  • введенный пользователем пароль (длина не более 512 бит, или 64 байт);
  • значение соли (произвольной длины);
  • число итераций (минимально допустимое значение — 1000, максимально допустимое — 4 294 967 295);
  • необходимая длина вычисляемого хеша.
 

Псевдослучайная хеш-функция HMAC_GOST3411

Сама функция HMAC_GOST3411 описана в другом нормативно-методическом документе Р 50.1.113—2016 и включает в себя следующие этапы:

  • дополнение нулями введенного пароля до длины в 64 байт (конечно, в том случае, если его длина меньше этого значения);
  • побайтовое сложение по модулю 2 получившегося на предыдущем этапе дополненного пароля с 64-байтовой константой ipad, в которой каждый байт равен 0x36;
  • конкатенация получившегося на предыдущем этапе значения с солью и подсчет «стрибог»-хеша из полученной строки;
  • конкатенация результата побайтового xor дополненного пароля с 64-байтовой константой opad (значение каждого байта равно 0x5c) с получившимся на предыдущем этапе результатом;
  • подсчет «стрибог»-хеша из результата предыдущего этапа.
Схема функции HMAC_GOST3411
Схема функции HMAC_GOST3411

Перед тем как писать код самой функции HMAC_GOST3411, необходимо определить нужные константы ipad и opad и написать функцию подсчета «стрибог»-хеша байтового массива произвольной длины.

 

Определение констант

Поскольку в ходе подсчета значений хеш-сумм мы оперируем 64-байтовыми блоками, то зададим размер этого блока:

#define BLOCK_SIZE 64

Константу ipad определим таким образом:

uint8_t i_pad[BLOCK_SIZE] = {
  0x36, 0x36, 0x36, 0x36, 0x36, ... , 0x36, 0x36
};

а константу opad таким:

uint8_t o_pad[BLOCK_SIZE] = {
  0x5c, 0x5c, 0x5c, 0x5c, 0x5c, ... , 0x5c, 0x5c
};

Для экономии места здесь константы описаны не полностью, на самом деле каждая из них длиной по 64 байт.

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее

Вариант 2. Открой один материал

Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.


  • Подпишись на наc в Telegram!

    Только важные новости и лучшие статьи

    Подписаться

  • Подписаться
    Уведомить о
    4 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии