HMAC-SHA256, HMAC-SHA512 и другие варианты

HMAC (Hash-based Message Authentication Code) в Jsrsasign строится поверх криптографических хеш-функций и используется для проверки целостности и подлинности сообщений. В основе механизма лежит секретный ключ и выбранный алгоритм хеширования, что делает результат устойчивым к подделке без знания ключа.

В библиотеке Jsrsasign HMAC реализован через модуль KJUR.crypto.Mac, который поддерживает набор стандартных алгоритмов: SHA-1, SHA-224, SHA-256, SHA-384 и SHA-512. На практике чаще всего применяются HMAC-SHA256 и HMAC-SHA512 как более устойчивые к современным атакам.


Внутренняя реализация HMAC в Jsrsasign следует стандарту RFC 2104. Концептуально процесс можно представить как два последовательных хеширования:

  • первый проход: ключ смешивается с внутренним паддингом
  • второй проход: результат первого хеша комбинируется с внешним паддингом и снова хешируется

В библиотеке это скрыто за API, где разработчик работает только с алгоритмом и входными данными.


Базовое использование KJUR.crypto.Mac

Основной класс для работы с HMAC — KJUR.crypto.Mac.

Пример создания HMAC-SHA256:

var mac = new KJUR.crypto.Mac({
  alg: "HmacSHA256",
  pass: "secret_key"
});

mac.updateString("message data");
var hmac = mac.doFinal();

Результат возвращается в шестнадцатеричном формате по умолчанию.


Использование SHA-512 в HMAC

HMAC-SHA512 применяется там, где требуется повышенная криптографическая стойкость и более длинный хеш-выход.

var mac = new KJUR.crypto.Mac({
  alg: "HmacSHA512",
  pass: "secret_key"
});

mac.updateString("important message");
var signature = mac.doFinal();

SHA-512 генерирует 512-битный результат, что увеличивает устойчивость к коллизиям по сравнению с SHA-256.


Быстрое вычисление HMAC через утилитарный метод

Jsrsasign предоставляет более компактный способ вычисления HMAC без явного создания объекта:

var hmac = KJUR.crypto.Mac.getMac(
  "message data",
  "secret_key",
  "sha256"
);

Аналогично для SHA-512:

var hmac = KJUR.crypto.Mac.getMac(
  "message data",
  "secret_key",
  "sha512"
);

Этот подход используется в случаях, когда требуется однократное вычисление значения без потоковой обработки данных.


Поддерживаемые алгоритмы HMAC

В Jsrsasign доступен следующий набор HMAC-алгоритмов:

  • HmacSHA1
  • HmacSHA224
  • HmacSHA256
  • HmacSHA384
  • HmacSHA512

Выбор зависит от требований к безопасности и совместимости с внешними системами.


Обработка данных и кодировка

При работе с HMAC важно учитывать, что входные данные интерпретируются как строки JavaScript. Для корректной криптографической совместимости используется UTF-8 кодировка.

mac.updateString("текст на русском языке");

При необходимости работы с бинарными данными используется другой метод:

mac.updateHex("4a6f686e");

или base64:

mac.updateString(b64data);

Неправильная кодировка является одной из частых причин несовпадения HMAC между разными платформами.


Работа с ключами

Секретный ключ в HMAC не обязан быть фиксированной длины, однако его длина влияет на стойкость результата.

Пример использования длинного ключа:

var key = "very_long_and_random_secret_key_value";
var mac = new KJUR.crypto.Mac({
  alg: "HmacSHA256",
  pass: key
});

mac.updateString("data");
var result = mac.doFinal();

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


Форматы вывода результата

Jsrsasign позволяет получать результат HMAC в разных форматах:

  • hex (по умолчанию)
  • base64

Пример получения base64:

var mac = new KJUR.crypto.Mac({
  alg: "HmacSHA256",
  pass: "secret"
});

mac.updateString("data");
var hex = mac.doFinal();

var b64 = hextob64(hex);

Функция hextob64 входит в утилиты Jsrsasign и часто используется для преобразования результата в формат, удобный для передачи по сети.


Потоковая обработка данных

Одним из преимуществ KJUR.crypto.Mac является возможность поэтапной обработки данных:

var mac = new KJUR.crypto.Mac({
  alg: "HmacSHA512",
  pass: "secret_key"
});

mac.updateString("part1 ");
mac.updateString("part2 ");
mac.updateString("part3");

var result = mac.doFinal();

Это полезно при работе с большими объемами данных или потоковыми источниками.


HMAC-SHA256 в протоколах аутентификации

HMAC-SHA256 часто используется в API-аутентификации, где запрос подписывается секретным ключом:

var message = "GET:/api/v1/user:timestamp=1710000000";

var mac = new KJUR.crypto.Mac({
  alg: "HmacSHA256",
  pass: "api_secret"
});

mac.updateString(message);
var signature = mac.doFinal();

Подпись затем передается вместе с запросом и проверяется сервером.


Сравнение SHA256 и SHA512 в HMAC

HMAC-SHA256:

  • меньший размер вывода (256 бит)
  • выше скорость вычисления
  • широко используется в API и веб-сервисах

HMAC-SHA512:

  • более длинный хеш (512 бит)
  • повышенная криптостойкость
  • предпочтителен в системах с высокими требованиями к безопасности

В Jsrsasign разница заключается только в параметре alg, остальная логика идентична.


Типичные ошибки при использовании HMAC

Некорректное сравнение строковых результатов:

if (signature == expected) { }

Безопаснее использовать строгие сравнения и нормализованные форматы (hex/base64).

Разные кодировки входных данных между клиентом и сервером также приводят к несовпадению HMAC.

Еще одна ошибка — использование разных алгоритмов на разных сторонах (например, SHA256 на клиенте и SHA1 на сервере), что делает результаты несовместимыми.


Работа с HMAC через функциональный API SHA классов

Jsrsasign также позволяет использовать низкоуровневые классы SHA напрямую, но это менее удобно для HMAC. Тем не менее архитектура библиотеки построена так, что KJUR.crypto.Mac выступает надстройкой над ними, автоматически применяя нужную хеш-функцию и внутренние операции XOR с padding.


Практика выбора алгоритма

SHA-1 постепенно считается устаревшим, несмотря на поддержку в библиотеке. SHA-256 стал стандартом де-факто. SHA-512 используется в системах, где требуется дополнительный запас безопасности или работа с 64-битной архитектурой.

В большинстве современных API предпочтение отдается HMAC-SHA256 как оптимальному балансу скорости и криптостойкости.