Вычислите HMAC-подпись для любого сообщения и секрета с помощью SHA-1, SHA-256, SHA-384 или SHA-512 с выводом в hex, base64 или base64url.
Коды аутентификации сообщений, локально. HMAC сочетает хеш-функцию с секретным ключом, чтобы получатель мог проверить и целостность, и подлинность. Вычисляется в вашем браузере через Web Crypto API.
Для чего нужен HMAC
Аутентификация, а не шифрование
HMAC ничего не скрывает. Он отвечает на другой вопрос: было ли это конкретное сообщение создано тем, кто владеет общим секретом, и не было ли оно изменено с тех пор? Результат — это тег фиксированного размера, который вы отправляете вместе с сообщением; получатель вычисляет его заново с тем же ключом и сравнивает. Совпадение тегов означает, что сообщение подлинно и цело. Несовпадение — что оно ни то, ни другое, и нельзя узнать, что именно.
Это делает HMAC основой подписей веб-хуков, подписывания API-запросов, подписанных куки и токенов сессий. Stripe, GitHub и большинство провайдеров веб-хуков подписывают свои полезные данные именно так, чтобы вы могли проверить, что запрос действительно пришёл от них, а не от того, кто угадал URL вашего эндпоинта.
Почему бы просто не хешировать ключ вместе с сообщением
Очевидная конструкция — SHA256(key + message) — уязвима для хешей семейства Merkle-Damgard, таких как SHA-1 и SHA-256. Эти хеши обрабатывают данные блоками и переносят состояние, поэтому злоумышленник, знающий корректный дайджест, может дописать данные и вычислить корректный дайджест для расширенного сообщения, даже не узнав ключ. Это атака продления длины, и она не теоретическая; она ломала реальные API.
Вложенная конструкция HMAC, H(key XOR opad || H(key XOR ipad || message)), закрывает эту брешь. Два прохода с разными дополненными ключами означают, что финальный дайджест — это не сырое внутреннее состояние хеша над данными, которые мог изменить злоумышленник. Именно поэтому всегда используйте HMAC, а не изобретайте свой собственный ключевой хеш.
Практические замечания
Выбирайте SHA-256, если только что-то извне не заставит поступить иначе. SHA-1 всё ещё безопасен внутри HMAC, поскольку конструкция не опирается на стойкость к коллизиям, но у новых систем нет причин использовать его, и аудиторы это отметят. SHA-512 не заметно сильнее для этой цели и иногда быстрее на 64-битном оборудовании.
Два нюанса реализации важнее, чем выбор хеша. Во-первых, сравнивайте теги за постоянное время — обычное сравнение строк возвращается при первом отличающемся байте, что раскрывает достаточно информации о времени, чтобы подделать тег побайтово. Во-вторых, ключи должны быть случайными байтами длиной не менее длины дайджеста, а не запоминающейся парольной фразой; ключи HMAC — это не хеши паролей, и они не растягиваются.
Часто задаваемые вопросы
Отправляется ли мой секрет куда-либо?
Нет. Ключ и сообщение никогда не покидают ваш браузер; подпись вычисляется локально через Web Crypto API, и ничего не передаётся и не сохраняется.
Какой алгоритм выбрать?
Используйте SHA-256 для новой работы. SHA-384 и SHA-512 повышают запас прочности за небольшую цену; SHA-1 существует только для совместимости с устаревшими системами.
В чём разница между base64 и base64url?
Base64url заменяет - и _ на + и / и убирает дополнение, что делает результат безопасным для размещения в URL, именах файлов и HTTP-заголовках.
Является ли HMAC видом шифрования?
Нет. Он доказывает, что сообщение пришло от владельца ключа и не было изменено, но само сообщение остаётся полностью читаемым. Добавьте TLS или шифрование, если нужна и секретность.
Почему бы просто не хешировать ключ вместе с сообщением?
Обычный SHA-2 уязвим к продлению длины: злоумышленник может дописать данные к подписанному сообщению и подделать корректный дайджест, не зная ключа. Вложенная конструкция HMAC блокирует это.
Как сравнивать два HMAC в коде?
С помощью сравнения за постоянное время, например crypto.timingSafeEqual. Обычное == завершается на первом отличающемся байте, что может раскрыть корректный тег побайтово.