HMAC (иногда расшифровывается как , код аутентификации (проверки подлинности) сообщений, использующий хеш-функции, или как , код аутентификации сообщений, использующий хеш-функции с ключом) — в информатике (криптографии), один из механизмов проверки целостности информации, позволяющий гарантировать то, что данные, передаваемые или хранящиеся в ненадёжной среде, не были изменены посторонними лицами (см. человек посередине). Механизм HMAC использует имитовставку (MAC), описан в RFC 2104, в стандартах организаций ANSI, IEF, ISO и NIST. MAC — стандарт, описывающий способ обмена данными и способ проверки целостности передаваемых данных с использованием секретного ключа. Два клиента, использующие MAC, как правило, используют общий секретный ключ. HMAC — надстройка над MAC; механизм обмена данными с использованием секретного ключа (как в MAC) и хеш-функций. В названии может уточняться используемая хеш-функция: HMAC-MD5, HMAC-SHA1, HMAC-RIPEMD128, HMAC-RIPEMD160 и т. п.
История Было замечено, что скорость работы хеш-функций (например, MD5, SHA-1, RIPEMD128, RIPEMD-160) обычно выше скорости работы симметричных блочных шифров (например, DES). Возникло желание использовать хеш-функции в MAC, а наличие готовых библиотек с реализациями различных хеш-функций только подтолкнуло эту идею.
Но использовать некоторые хеш-функции в MAC было невозможно. Например, хеш-функция MD5 не может применяться в MAC, так как принимает только один аргумент — данные (строку, последовательность байт) и не использует секретного ключа.
В июне 1996 годаMihir Bellare, Ran Canetti и Hugo Krawczyk. «Keying hash functions for message authentication». 1996. Скачать PDF . Хьюго Кравчик (, сотрудник фирмы IBM), (, сотрудник калифорнийского университета в Сан-Диего (UCSD)) и Ран Каннетти (, сотрудник фирмы IBM) опубликовали описание механизма HMAC, а в феврале 1997 года ими же был выпущен RFC 2104. В HMAC данные «смешивались» с ключом, и хеш-функция применялась дважды.
Были предложены и другие механизмы, позволяющие одновременно использовать данные и секретный ключ в существующих алгоритмах хеширования, но HMAC получил наибольшую поддержку.
Преимущества HMAC: возможность использования хеш-функций, уже имеющихся в программном продукте; отсутствие необходимости внесения изменений в реализации существующих хеш-функций (внесение изменений может привести к ухудшению производительности и/или ухудшению криптостойкости); возможность замены хеш-функции в случае появления более безопасной или более быстрой хеш-функции.
Механизм HMAC был описан в стандартах организаций ANSI, IETF, ISO и NIST.
Применение Реализация HMAC является обязательной () для протокола IPsec.
HMAC используется и в других протоколах интернета, например, TLS.
Описание алгоритма Обозначения b, block_size — размер блока в байтах; H, hash — хеш-функция; ipad — блок вида ( 0x36 0x36 0x36 ... 0x36 ), где байт 0x36 повторяется b раз; 0x36 — константа, магическое число, приведённое в RFC 2104; «i» от «inner»; K, key — секретный ключ (общий для отправителя и получателя); K0 — изменённый ключ K (уменьшенный или увеличенный до размера блока (до b байт)); L — размер в байтах строки, возвращаемой хеш-функцией H; L зависит от выбранной хеш-функции и обычно меньше размера блока; Хеш-функция H b, байт L, байт MD5 64 16 SHA-1 64 20 SHA-224 64 28 SHA-256 64 32 SHA-512/224 128 28 SHA-512/256 128 32 SHA-384 128 48 SHA-512 128 64 SHA3-224 144 28 SHA3-256 136 32 SHA3-384 104 48 SHA3-512 72 64 out = H( in )b = length( in )L = length( out ) opad — блок вида ( 0x5c 0x5c 0x5c ... 0x5c), где байт 0x5c повторяется b раз; 0x5c — константа, магическое число, приведённое в RFC 2104; «o» от «outer»; text — сообщение (данные), которое будет передаваться отправителем и подлинность которого будет проверяться получателем; n — длина сообщения text в битах.
Алгоритм HMAC можно записать в виде одной формулы:
где: «» — операция «побитовое исключающее ИЛИ» или «xor»; «» — операция «склейка строк» (последовательностей байт).
Схема работы алгоритма HMAC приведена на рисунках.
Этапы работы алгоритм HMAC перечисленные ниже.
Получить K0 путём уменьшения или увеличения ключа K до размера блока (до b байт).
1.1. Если длина ключа K равна размеру блока, то копируем K в K0 без изменений и переходим к шагу 2. IF length( K ) == b THEN : K_0 = K END_IF
1.2. Если длина ключа K больше размера блока, то к ключу K применяем хеш-функцию H, получаем строку размером в L байт, добавляем нули к правой части этой строки для создания строки размером в b байт, копируем результат в K0 и переходим к шагу 2. IF length( K ) > b THEN : x = H( K ) K_0 = zeros( x, b - L ) END_IF
1.3. Если длина ключа K меньше размера блока, то добавляем нули к правой части K для создания строки размером в b байт, копируем результат в K0 (например, если length( К ) = 20 (в байтах) и b = 64 (в байтах), то к правой части К будет добавлено 64 - 20 = 44 нулевых байта (0x00)) и переходим к шагу 2. IF length( K ) < b THEN : K_0 = zeros( K, b - length( K ) ) END_IF
Получить блок Si размером в b байт с помощью операции «побитовое исключающее ИЛИ» («xor», ): Si = xor( K0, ipad ) = K0 ipad.
Получить блок So размером в b байт с помощью операции «побитовое исключающее ИЛИ»: So = xor( K0, opad ) = K0 opad.
Разбить сообщение (данные, набор байт) text на блоки размером b байт. Склеить строку (последовательность байт) Si с каждым блоком сообщения М. К строке, полученной на прошлом шаге, применить хеш-функцию Н. Склеить строку So со строкой, полученной от хеш-функции H на прошлом шаге. К строке, полученной на прошлом шаге, применить хеш-функцию Н.
Ключи размером меньше L байт, считаются небезопасными (). Рекомендуется выбирать ключи случайным образом и регулярно их менять. Ключи размером больше L байт, существенно не увеличивают стойкость функции, могут использоваться, если имеются сомнения в случайности данных, используемых для создания ключа и получаемых от генератора случайных чисел.
Размер ключа К должен быть больше или равен L/2 байт.
На рисунке показана реализация алгоритма HMAC-MD5. Реализация отличается использованием функции F. Использование этой реализации целесообразно, если большинство сообщений, для которых вычисляется MAC, короткие. Функция F — функция сжатия для хеш-функции H. В качестве аргументов F принимает переменную n и блок длиной в b байт. F производит разбиение блока на цепочку звеньев с длиной каждого звена в n байт. Функция F вызывается для каждого нового ключа один раз.
Псевдокод Далее приведён пример реализации HMAC на псевдокоде:
FUNCTION hmac( key, msg ) :
IF length( key ) > block_size THEN :
key = hash( key )
END_IF
IF length( key ) < block_size THEN:
key = key ∥ zeroes( block_size - length( key ))
END_IF
ipad = [ '\x36' * block_size ]
opad = [ '\x5c' * block_size ]
ikeypad = ipad ⊕ key
okeypad = opad ⊕ key
RETURN hash( okeypad ∥ hash( ikeypad ∥ msg ) )
END_FUNCTION
Примеры кода Пример реализации алгоритма HMAC-MD5 с помощью функций стандартной библиотеки языка Python: import hmac, hashlib print(hmac.new( key=b'secret_shared_key', msg=open('message.txt', 'rb').read(), digestmod=hashlib.md5 ).hexdigest())
Одна из возможных реализаций алгоритма HMAC-MD5 на языке PHP: function hmac ( $key, $data ) { $b = 64; // block size according RFC 2104 if ( strlen( $key ) > $b ) { $key = pack( "H*", md5( $key ) );
$key = str_pad( $key, $b, chr(0x00) ); $ipad = str_pad( '', $b, chr(0x36) ); $opad = str_pad( '', $b, chr(0x5c) ); $k_ipad = $key ^ $ipad ; $k_opad = $key ^ $opad; return md5( $k_opad . pack("H*", md5( $k_ipad . $data ) ) );
Примеры работы Продемонстрируем пример работы алгоритма для различных входных данных.
Первый параметр — ключ K размером в 160 бит (20 байт). Второй параметр — сообщение text, которое будет передаваться отправителем и подлинность которого будет проверяться получателем. На выходе мы получаем код аутентификации размером в 160 бит.
HMAC( K, text ) = HMAC( 0000000000000000000000000000000000000000, "" ) = 740ca4e7a701540b385df12fe57cff57
HMAC( K, text ) = HMAC( 0000000000000000000000000000000000000000, "Hello World" ) = a0e026219366a56cf843bd2051831327
HMAC( K, text ) = HMAC( 0000000000000000000000000000000000000001, "1" ) = c6b1d8489a204918643086ce346b86bc
Более подробно рассмотрим алгоритм HMAC-SHA1 с ключом размером в 20 байт.
Имеем: текстовое сообщение text = "Hello World" и 20-байтовый ключ в шестнадцатеричном виде K = 0x707172737475767778797a7b7c7d7e7f80818283
Шаг 1. Дополняем ключ K нулевыми байтами до размера блока. Размер блока хеш-функции SHA-1 равен 64 байтам. K0: 70717273 74757677 78797a7b 7c7d7e7f 80818283 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
Шаг 2. Выполняем операцию «побитовое исключающее ИЛИ» c константой 0x36. K0 ipad : 46474445 42434041 4e4f4c4d 4a4b4849 b6b7b4b5 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636
Шаг 3. Выполняем склейку исходного сообщения со строкой, полученной на шаге 2. ( K ipad ) || text : 46474445 42434041 4e4f4c4d 4a4b4849 b6b7b4b5 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636 36363636 48656c6c 6f20576f 726c64
Шаг 4. Применим хеш-функцию SHA-1 к строке, полученной на прошлом шаге. H( ( K ipad ) || text ) : 0d42b899 d804e19e bfd86fc4 4f414045 dfc9e39a
Шаг 5. Выполним операцию «побитовое исключающее ИЛИ» c константой 0x5c. K0 opad : 2c2d2e2f 28292a2b 24252627 20212223 dcdddedf 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c
Шаг 6. Склейка строки, полученной на шаге 4, со строкой, полученной на шаге 5. ( K0 opad ) || H( ( K ipad ) || text ) : 2c2d2e2f 28292a2b 24252627 20212223 dcdddedf 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 5c5c5c5c 0d42b899 d804e19e bfd86fc4 4f414045 dfc9e39a
Шаг 7. Применим хеш-функцию SHA-1 к строке, полученной на прошлом шаге. HMAC( K, text ) = H( ( K0 opad ) || H( ( K ipad ) || text ) ) : 2e492768 aa339e32 a9280569 c5d02626 2b912431
Итог. Получили строку HMAC( K, text ) размером в 20 байт.
Вопросы использования Полученный код аутентичности позволяет убедиться в том, что данные не изменялись каким бы то ни было способом с тех пор, как они были созданы, переданы или сохранены доверенным источником. Для такого рода проверки необходимо, чтобы, например, две доверяющие друг другу стороны заранее договорились об использовании секретного ключа, который известен только им. Тем самым гарантируется аутентичность источника и сообщения. Недостаток такого подхода очевиден — необходимо наличие двух доверяющих друг другу сторон.
Безопасность Безопасность любой функции MAC на основе встроенных хеш-функций зависит от криптостойкости базовой хеш-функции. Привлекательность HMAC — в том, что его создатели смогли доказать точное соотношение между стойкостью встроенных хеш-функций и стойкостью HMAC.
Безопасность функции имитовставки (MAC) обычно выражается в терминах вероятности успешного взлома с количеством времени, потраченного на это, а также на получение пары (сообщение — MAC), созданной с тем же ключом. В сущности, это доказано в BELL96a, что при данном уровне усилия (время, сообщение — MAC) на сообщение, сгенерированное конечным пользователем, вероятность успешной атаки на HMAC эквивалентна атаке, произведённой на встроенную хеш-функцию: В первом типе атаки мы можем рассматривать функции сжатия F в качестве эквивалента хеш-функции, применяемой для сообщения, состоящие из единичного блока длиной B бит. Для этого на вход хеш-функции подаётся случайное значение длиной N бит. Нападение на хеш-функцию требует или полного перебора ключа, который обладает уровнем сложности порядка , или с помощью атаки «дней рождения», которая является частным случаем второго нападения, что обсуждается далее.