Перейти к содержанию

HMAC

Хеш доказывает, что сообщение не изменилось, но не говорит, кто его отправил: посчитать SHA-256 может любой. HMAC добавляет к хешу секретный ключ, и проверить код может только тот, кто этим ключом владеет.

Обновлено Редакция GAW

HMAC (Hash-based Message Authentication Code) — код аутентификации сообщения, построенный на криптографической хеш-функции и секретном ключе, который разделяют отправитель и получатель. Его определяет RFC 2104. Получатель вычисляет HMAC от принятого сообщения своим экземпляром ключа и сравнивает с присланным: совпадение означает, что сообщение не изменено и создано владельцем ключа. В отличие от CRC и простого хеша, подделать HMAC без ключа нельзя.

Формула

По RFC 2104 (разд. 2) для хеш-функции H с длиной блока B байт и длиной дайджеста L байт:

HMAC(K,text)=H((K⊕opad) ∥ H((K⊕ipad) ∥ text))\mathrm{HMAC}(K, \text{text}) = H\big((K \oplus \text{opad}) \,\|\, H((K \oplus \text{ipad}) \,\|\, \text{text})\big)

где ipad — байт 0x36, повторённый B раз, opad — байт 0x5C, повторённый B раз, а ключ K предварительно дополнен нулями до B байт. Два вложенных вызова хеша защищают от атак на простую конструкцию «хеш от ключа и сообщения». Промежуточные состояния после блоков K ⊕ ipad и K ⊕ opad можно вычислить один раз и хранить (разд. 4) — это экономит два блока на каждое короткое сообщение, но хранить их нужно как секрет.

ПараметрMD5SHA-1SHA-256
Длина блока B64 байта64 байта64 байта
Дайджест L16 байт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 (наш расчёт по правилу половины дайджеста).

Источники

  1. 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
  2. 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
  3. 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()
Страница помогла?

Нашли ошибку? ·