HMAC (Hash-based Message Authentication Code) представляет собой механизм проверки целостности и подлинности сообщений, основанный на криптографических хеш-функциях и секретном ключе. Основная идея заключается в том, что одна и та же входная строка при наличии одного и того же ключа всегда приводит к одинаковому значению, а любое изменение данных или ключа приводит к полностью другому результату.
HMAC строится на сочетании двух компонентов:
Алгоритм использует два этапа хеширования с модифицированным ключом:
Формально процесс можно представить как:
HMAC(K, m) = H((K ⊕ opad) || H((K ⊕ ipad) || m))
где:
Двойное хеширование не является случайным усложнением. Оно решает несколько криптографических проблем:
Хеш-функции вроде SHA-256 построены на итеративных конструкциях, что делает их уязвимыми при использовании без ключа. HMAC устраняет этот недостаток за счёт введения секретного контекста в обе стадии вычисления.
HMAC обладает набором характеристик, которые делают его стандартом де-факто в системах аутентификации сообщений:
Обычные хеш-функции (например, SHA-256) используются для проверки целостности данных, но не обеспечивают защиту от подделки:
HMAC добавляет секретный ключ, что приводит к следующим изменениям:
HMAC используется в системах, где требуется проверка подлинности без шифрования данных:
Библиотека Jsrsasign предоставляет криптографические функции через
пространство имён KJUR.crypto. Для работы с HMAC
используется объект Mac.
Основной принцип — указание алгоритма и секретного ключа, после чего вычисляется MAC (Message Authentication Code).
const { KJUR } = require("jsrsasign");
const message = "data to protect";
const key = "secret_key";
const hmac = new KJUR.crypto.Mac({
alg: "HmacSHA256",
pass: key
});
hmac.updateString(message);
const result = hmac.doFinal();
console.log(result);
Результатом является шестнадцатеричная строка, представляющая криптографический код аутентификации.
const { KJUR } = require("jsrsasign");
const mac = new KJUR.crypto.Mac({
alg: "HmacSHA1",
pass: "my_secret"
});
mac.updateString("important message");
const hmacValue = mac.doFinal();
Несмотря на наличие SHA-1, в современных системах предпочтение отдаётся SHA-256 и выше из-за криптоаналитических уязвимостей SHA-1.
Jsrsasign поддерживает поэтапное добавление данных, что важно при работе с потоками:
const mac = new KJUR.crypto.Mac({
alg: "HmacSHA256",
pass: "key"
});
mac.updateString("part1 ");
mac.updateString("part2 ");
mac.updateString("part3");
const result = mac.doFinal();
Это позволяет вычислять HMAC без необходимости хранить всё сообщение в памяти целиком.
Одной из типичных ошибок является использование HMAC без криптографически стойкого ключа. Ключ должен обладать достаточной энтропией и не быть предсказуемым.
Другие ошибки включают:
==, что может
приводить к тайминговым атакам| Алгоритм | Уровень безопасности | Рекомендация |
|---|---|---|
| HmacMD5 | низкий | не использовать |
| HmacSHA1 | средний | устаревший стандарт |
| HmacSHA256 | высокий | основной выбор |
| HmacSHA512 | очень высокий | предпочтителен для критичных систем |
Jsrsasign реализует HMAC через комбинацию стандартных хеш-алгоритмов и промежуточного буферного состояния. При этом:
HMAC остаётся устойчивым даже при частичном знании входных данных благодаря следующим свойствам:
С практической точки зрения безопасность определяется не только алгоритмом, но и качеством ключа и его управлением в системе.