Брешь, которую оставляет обычный хеш
Криптографический хеш доказывает целостность: если дайджест по-прежнему совпадает, данные не были изменены. Но он ничего не доказывает о том, кто их произвёл. Кто угодно может захешировать сообщение, так что дайджест, отправленный рядом с сообщением, не даёт защиты от атакующего, который просто меняет сообщение и пересчитывает дайджест. Здесь нет секрета, поэтому нет ничего, что мог бы сделать только законный отправитель.
закрывает эту брешь. Это код аутентификации сообщения: значение, доказывающее, что сообщение не было подменено и пришло от того, кто владеет общим секретным ключом. Проверяющий пересчитывает 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 вычисляется локально.