Содержание статьи
- Общая схема и исходные данные
- Псевдослучайная хеш-функция HMAC_GOST3411
- Определение констант
- Функция подсчета «стрибог»-хеша
- Пишем непосредственно саму функцию HMAC_GOSTR3411
- Password-Based Key Derivation Function
- Функция вычисления значения первой итерации для
i
-го цикла - Функция вычисления значения последующих итераций для
i
-го цикла - Ксорим результаты всех итераций
- Собираем результаты расчетов каждого цикла и определяем окончательный хеш
- Заключение
Как выглядят записи в базе данных пользователей «хороших систем контроля доступа»? Примерно так (здесь видны имя учетной записи пользователя, значение соли и значение хеша):
...
"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 (да-да, это тот самый «Стрибог» — похоже, нынче без него никуда).
Общая схема и исходные данные
Основу алгоритма получения хеша составляет так называемая функция диверсификации 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, необходимо определить нужные константы 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»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»