HMAC
Подпись сообщения секретным ключом: по ней получатель проверяет, что данные не изменили по дороге и отправил их тот, у кого есть ключ.
HMAC (Hash-based Message Authentication Code) — код проверки подлинности сообщения на основе хеш-функции и секретного ключа. Отправитель и получатель заранее знают общий ключ. По коду HMAC получатель убеждается в двух вещах: сообщение не меняли по дороге, и создал его тот, у кого есть ключ. Алгоритм описан в стандарте RFC 2104 в 1997 году и с тех пор встроен почти во все протоколы обмена данными.
Как работает HMAC
- Отправитель вычисляет HMAC от сообщения и секретного ключа — получается строка фиксированной длины, например 64 шестнадцатеричных символа для HMAC-SHA256.
- Сообщение уходит вместе с этим кодом.
- Получатель сам вычисляет HMAC от полученного сообщения тем же ключом и сравнивает с присланным. Совпало — данные подлинные. Изменился хотя бы один символ сообщения — код получится совсем другим.
Посчитать HMAC можно одной командой:
echo -n "amount=1000&order=42" | openssl dgst -sha256 -hmac "secret-key"
Внутри алгоритм дважды применяет хеш-функцию (SHA-256 или другую) к сообщению, смешанному с ключом. Такая схема защищает от атак, которым подвержен наивный вариант «хеш от ключа и сообщения подряд».
Чем HMAC отличается от хеша и электронной подписи
- Обычный хеш (например, SHA-256 файла) ключа не использует. Его может пересчитать кто угодно, поэтому он подтверждает только целостность: злоумышленник изменит данные и просто посчитает новый хеш.
- HMAC требует секретного ключа, поэтому подделать код без ключа нельзя. Но ключ один на обе стороны: HMAC доказывает подлинность друг другу, а не третьему лицу.
- Электронная подпись использует пару ключей: закрытым подписывают, открытым проверяет кто угодно. Отказаться от своей подписи нельзя, поэтому юридически значимые документы подписывают ею, в России — по ГОСТ.
Важно: HMAC не скрывает содержимое. Сообщение остается читаемым, и для конфиденциальности нужно шифрование — например, передача по TLS.
Где применяется
- Подпись запросов к API. Клиент подписывает каждый запрос к REST API общим ключом — так устроена, например, подпись запросов в Amazon Web Services.
- Уведомления (webhooks). Платежные сервисы и GitHub подписывают свои уведомления HMAC-SHA256, чтобы получатель отличил настоящие от поддельных.
- Токены. JWT с алгоритмом HS256 подписан именно HMAC-SHA256.
- Одноразовые коды. Шестизначные коды в приложениях-аутентификаторах (алгоритмы HOTP и TOTP) вычисляются через HMAC от общего секрета и счетчика или текущего времени.
- Протоколы защиты связи. Внутри TLS функции на основе HMAC участвуют в выработке ключей шифрования.
При интеграции банковских систем с платежными и партнерскими сервисами проверка таких подписей — обязательная часть обмена данными.
Как использовать HMAC правильно
- Ключ — длинный и случайный: для HMAC-SHA256 не короче 32 байт.
- Ключ хранят в защищенном хранилище секретов, а не в коде и не в репозитории.
- Коды сравнивают функцией постоянного времени (
hmac.compare_digestв Python,hash_equalsв PHP), иначе по времени ответа можно подобрать правильный код. - В подписываемые данные включают время или одноразовый номер запроса, чтобы перехваченное сообщение нельзя было отправить повторно.
- Ключи периодически меняют, а при подозрении на утечку — сразу.