HMAC
Хеш доказывает, что сообщение не изменилось, но не говорит, кто его отправил: посчитать SHA-256 может любой. HMAC добавляет к хешу секретный ключ, и проверить код может только тот, кто этим ключом владеет.
Обновлено Редакция GAW
Содержание
HMAC (Hash-based Message Authentication Code) — код аутентификации сообщения, построенный на криптографической хеш-функции и секретном ключе, который разделяют отправитель и получатель. Его определяет RFC 2104. Получатель вычисляет HMAC от принятого сообщения своим экземпляром ключа и сравнивает с присланным: совпадение означает, что сообщение не изменено и создано владельцем ключа. В отличие от CRC и простого хеша, подделать HMAC без ключа нельзя.
Формула
По RFC 2104 (разд. 2) для хеш-функции H с длиной блока B байт и длиной дайджеста L байт:
где ipad — байт 0x36, повторённый B раз, opad — байт 0x5C, повторённый B раз, а ключ K предварительно дополнен нулями до B байт. Два вложенных вызова хеша защищают от атак на простую конструкцию «хеш от ключа и сообщения». Промежуточные состояния после блоков K ⊕ ipad и K ⊕ opad можно вычислить один раз и хранить (разд. 4) — это экономит два блока на каждое короткое сообщение, но хранить их нужно как секрет.
| Параметр | MD5 | SHA-1 | SHA-256 |
|---|---|---|---|
| Длина блока B | 64 байта | 64 байта | 64 байта |
| Дайджест L | 16 байт | 20 байт | 32 байта |
| Минимальный ключ (рекомендация RFC 2104) | 16 байт | 20 байт | 32 байта |
| Минимум при усечении | 80 бит | 80 бит | 128 бит |
Значения для MD5 и SHA-1 — из RFC 2104; для SHA-256 длина дайджеста 32 байта и блок 64 байта следуют из определения функции, а минимум усечения — половина дайджеста по правилу разд. 5 (наш расчёт). Проверить реализацию можно по векторам RFC 4231: для ключа из 20 байт 0x0b и текста «Hi There» HMAC-SHA-256 равен b0344c61…2e32cff7.
Ключ и усечение
Ключ может быть любой длины до B; более длинный сначала хешируется до L байт. Ключ короче L настоятельно не рекомендуется, а длиннее L стойкости почти не добавляет (разд. 3). Ключи выбирают случайно — на контроллере источником служит аппаратный ГСЧ — и периодически обновляют. Вывод разрешено усекать до t старших бит с обозначением HMAC-H-t, например HMAC-SHA1-80, но не меньше половины дайджеста и не меньше 80 бит (разд. 5).
Где применяется
- Сообщения по сети. Подпись команд и телеметрии между устройством и собственным сервером, когда у обеих сторон один ключ; в TLS 1.3 значения HMAC служат binder'ами в расширении
pre_shared_keyпри аутентификации по PSK. Как встроить код в кадр протокола, разобрано в статье «Реализация протоколов». - Прошивки. HMAC годится, когда проверяющий тоже владеет ключом: например, устройство проверяет образ обновления по воздуху от своего сервера. Но любой, кто может проверить HMAC, может его и создать, поэтому для образов, которые проверяют массово выпущенные устройства, используют подписи с открытым ключом — см. безопасную загрузку.
- Аппаратный блок. В ESP32-S3 модуль HMAC считает SHA256-HMAC с ключом, прожжённым в один из блоков eFuse 4–9, который можно сделать нечитаемым для программы; у каждого блока задано назначение: HMAC для прошивки (значение 8), ключ для блока RSA Digital Signature или разрешение программно отключённого JTAG, для чего токеном служит HMAC-SHA256 от 32 нулевых байт. Так ключ никогда не попадает в ОЗУ, в отличие от программной реализации в mbedTLS. Шифрование при этом остаётся отдельной задачей — её решает AES.
Частые вопросы
Чем HMAC отличается от обычного хеша?
Хеш считается только от сообщения, и подделать пару «сообщение — хеш» может любой. В HMAC к сообщению примешивается секретный ключ, по RFC 2104 — дважды: внутренний хеш от (K ⊕ ipad) и текста, затем внешний от (K ⊕ opad) и внутреннего результата. Не зная ключа, верный код не вычислить, поэтому HMAC подтверждает и целостность, и то, что отправитель владеет ключом. При этом сама хеш-функция используется без изменений, и её можно заменить другой.
Какой длины должен быть ключ HMAC?
По RFC 2104 ключ может быть любой длины до размера блока хеш-функции B (64 байта для SHA-1 и MD5); более длинный ключ сначала хешируется. Минимальная рекомендуемая длина — длина дайджеста L: ключ короче L настоятельно не рекомендуется, а длиннее L стойкости заметно не добавляет. Ключ должен быть случайным — на микроконтроллере его берут от аппаратного генератора — и периодически обновляться.
Можно ли укоротить HMAC, чтобы сэкономить место в пакете?
Да, RFC 2104 (разд. 5) допускает усечение до t старших бит с обозначением HMAC-H-t, например HMAC-SHA1-80. Ограничения: не меньше половины длины дайджеста и не меньше 80 бит. Для HMAC-SHA256 это минимум 128 бит, то есть 16 байт вместо 32 (наш расчёт по правилу половины дайджеста).
Источники
- IETF. RFC 2104 HMAC: Keyed-Hashing for Message Authentication. H. Krawczyk, M. Bellare, R. Canetti, February 1997 — разд. 1: MAC — проверка целостности на секретном ключе между двумя сторонами; цели HMAC — использовать хеш-функцию без изменений, сохранить её скорость, просто обращаться с ключом, легко заменять хеш; разд. 2: B — длина блока хеша в байтах (64 для MD5 и SHA-1), L — длина дайджеста (16 для MD5, 20 для SHA-1); ключ любой длины до B, более длинный сначала хешируется; минимальная рекомендуемая длина ключа — L; ipad = байт 0x36, повторённый B раз, opad = 0x5C B раз; HMAC = H(K XOR opad, H(K XOR ipad, text)); ключ дополняется нулями до B байт; разд. 3: ключ короче L настоятельно не рекомендуется, длиннее L стойкости заметно не добавляет; ключи выбирают случайно и периодически обновляют; разд. 4: промежуточные состояния после блоков K XOR ipad и K XOR opad можно вычислить один раз и хранить как секрет; разд. 5: вывод можно усекать до t бит, не меньше половины дайджеста и не меньше 80 бит, обозначение HMAC-H-t, например HMAC-SHA1-80
- IETF. RFC 4231 Identifiers and Test Vectors for HMAC-SHA-224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512. M. Nystrom, December 2005 — разд. 3.1: идентификаторы id-hmacWithSHA256 и др.; разд. 4.1: векторы сверены тремя независимыми реализациями; разд. 4.2, Test Case 1: ключ — 20 байт 0x0b, данные «Hi There» (4869205468657265), HMAC-SHA-256 = b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7
- Espressif. ESP-IDF Programming Guide v6.1, ESP32-S3: Hash-Based Message Authentication Code (HMAC) — модуль аппаратно вычисляет SHA256-HMAC с ключом, прожжённым в блок eFuse; ключ можно сделать недоступным для всего, кроме криптографических модулей; шесть блоков eFuse 4–9 (HMAC_KEY0–HMAC_KEY5), у каждого назначение (key purpose): 8 — HMAC для программы, 7 и 5 — ключ для RSA Digital Signature, 6 и 5 — разрешение программно отключённого JTAG; расчёт идёт, только если назначение блока совпадает с запрошенным; API для программного использования — psa_mac_compute(); ключ для JTAG — 256-битный, токен = HMAC-SHA256 от 32 нулевых байт; ключ записывают esp_efuse_write_key() с ESP_EFUSE_KEY_PURPOSE_HMAC_UP и защищают от чтения esp_efuse_set_read_protect()
Нашли ошибку? ·
Смотрите также
- Криптографическая хеш-функция (SHA)Функция, сжимающая сообщение в дайджест, к которому нельзя подобрать другое сообщение
- TLS-PSKАутентификация TLS общим секретом: наборы по RFC 4279, режимы TLS 1.3, зачем на МК и чем платят
- Безопасная загрузкаЗапуск только подписанной прошивки: подпись, ключи в OTP, откат версий
- OTA (обновление по воздуху)Обновление прошивки ESP32 из работающей программы по сети
- CRCЦиклический избыточный код для обнаружения ошибок
- AES (Advanced Encryption Standard)Стандартный блочный шифр с блоком 128 бит и ключами 128, 192 или 256 бит
- Аппаратный генератор случайных чиселБлок микроконтроллера, который выдаёт случайные числа на основе физического шума
- Реализация протокола обменаКадры по паузе, длине и разделителю, COBS, CRC-16, таймауты, разбор потока