Брешь, которую оставляет обычный хеш

Криптографический хеш доказывает целостность: если дайджест по-прежнему совпадает, данные не были изменены. Но он ничего не доказывает о том, кто их произвёл. Кто угодно может захешировать сообщение, так что дайджест, отправленный рядом с сообщением, не даёт защиты от атакующего, который просто меняет сообщение и пересчитывает дайджест. Здесь нет секрета, поэтому нет ничего, что мог бы сделать только законный отправитель.

закрывает эту брешь. Это код аутентификации сообщения: значение, доказывающее, что сообщение не было подменено и пришло от того, кто владеет общим секретным ключом. Проверяющий пересчитывает HMAC тем же ключом; если совпадает, сообщение подлинно.

Добавление ключа, правильным образом

Очевидная идея, просто захешировать ключ и сообщение вместе как hash(ключ + сообщение), тонко небезопасна. Многие хеш-функции (включая семейство ) построены на конструкции, уязвимой к атаке расширения длины: зная hash(ключ + сообщение) и длину секрета, атакующий может вычислить корректный хеш для ключ + сообщение + добавка, так и не узнав ключ. Это позволило бы ему подделать расширенное, всё ещё корректное сообщение.

HMAC (определён в RFC 2104) избегает этого, хешируя дважды, каждый раз по-разному подмешивая ключ. Концептуально он вычисляет:

HMAC(K, m) = H( (K XOR opad) + H( (K XOR ipad) + m ) )

где ipad и opad — две фиксированные константы заполнения. Внутренний хеш связывает ключ с сообщением; внешний хеш оборачивает результат, чтобы трюк расширения длины не мог до него дотянуться. Формулу запоминать не нужно, суть в том, что именно вложенная структура, а не небрежная конкатенация, делает HMAC надёжным.

HMAC против цифровой подписи

Оба доказывают подлинность, но модель доверия различается:

  • HMAC симметричен. Один секретный ключ разделяется обеими сторонами. Кто может проверить HMAC, тот может и создать его, так что это работает, когда обе стороны уже разделяют ключ, но не могут доказать авторство третьей стороне.
  • Цифровая подпись асимметрична. Подписывающий использует приватный ключ; кто угодно может проверить открытым ключом. Это доказывает авторство всему миру, ценой более высоких вычислительных затрат.

Выбирайте HMAC, когда две системы разделяют секрет и нуждаются в быстрой взаимной аутентификации; выбирайте подпись, когда проверяющие не должны иметь возможность подделать то, что они проверяют.

Где вы встречаете HMAC

  • Подпись запросов API. Схемы вроде Signature Version 4 подписывают каждый запрос с HMAC-SHA256, чтобы сервер мог подтвердить, что вызывающий владеет секретным ключом.
  • Вебхуки. Провайдер отправляет HMAC полезной нагрузки в заголовке; ваш эндпоинт пересчитывает его, чтобы отклонять поддельные вызовы.
  • с . Токен, подписанный HS256, буквально является HMAC-SHA256 над заголовком и полезной нагрузкой токена. Инструмент HMAC использует ровно ту же конструкцию Web Crypto, что и проверяющий JWT, так что оба согласуются по замыслу.

Ваше сообщение и ключ никогда не покидают браузер; HMAC вычисляется локально.