HMAC-SHA256 и HMAC-SHA512

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

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

В CryptoJS HMAC реализован как обёртка над хэш-функциями. Основная структура выглядит следующим образом:

  • криптографическая хэш-функция (SHA-256 или SHA-512)
  • секретный ключ (строка, WordArray или байтовый массив)
  • входное сообщение

HMAC вычисляется по стандартной схеме:

  • ключ нормализуется до длины блока хэш-функции
  • создаются внутренний и внешний паддинги (ipad и opad)
  • выполняется двойное хэширование

Формально:

HMAC(K, m) = H((K opad) ;||; H((K ipad) ;||; m))

где:

    1. — хэш-функция (SHA-256 или SHA-512)
    1. — секретный ключ
    1. — сообщение
  • (opad), (ipad) — фиксированные константы

Подключение CryptoJS

Библиотека подключается в классическом варианте через CDN или npm:

import CryptoJS from "crypto-js";

или

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js"></script>

HMAC-SHA256

SHA-256 используется как стандартный баланс между безопасностью и производительностью. Длина хэша составляет 256 бит (32 байта).

Базовое использование

const secret = "super_secret_key";
const message = "important data";

const hash = CryptoJS.HmacSHA256(message, secret).toString();

console.log(hash);

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

Использование с WordArray

CryptoJS работает через внутренний тип данных WordArray, что важно при работе с бинарными данными:

const key = CryptoJS.enc.Utf8.parse("super_secret_key");
const msg = CryptoJS.enc.Utf8.parse("important data");

const hash = CryptoJS.HmacSHA256(msg, key);

Кодирование результата

HMAC можно представить в разных форматах:

const hex = CryptoJS.HmacSHA256(message, secret).toString(CryptoJS.enc.Hex);
const base64 = CryptoJS.HmacSHA256(message, secret).toString(CryptoJS.enc.Base64);

Hex используется для логирования и API-подписей, Base64 — для передачи в HTTP-заголовках.

HMAC-SHA512

SHA-512 обеспечивает более высокий уровень криптографической стойкости за счёт длины хэша 512 бит (64 байта). Он предпочтителен в системах с повышенными требованиями к безопасности.

Базовая реализация

const secret = "super_secret_key";
const message = "important data";

const hash = CryptoJS.HmacSHA512(message, secret).toString();

console.log(hash);

Особенности SHA-512 в CryptoJS

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

Работа с бинарными данными

const key = CryptoJS.enc.Utf8.parse("super_secret_key");
const msg = CryptoJS.enc.Utf8.parse("important data");

const hash = CryptoJS.HmacSHA512(msg, key);

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

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

Размер выхода

|SHA-256| = 256 bits, |SHA-512| = 512 bits

Производительность

  • SHA-256 быстрее на 32-битных системах
  • SHA-512 часто быстрее на 64-битных архитектурах
  • CryptoJS реализует обе функции на JavaScript, поэтому разница зависит от окружения

Криптографическая стойкость

  • SHA-256: достаточен для большинства API и веб-сервисов
  • SHA-512: предпочтителен для долгосрочной защиты и криптографических систем с повышенными требованиями

Практическое применение HMAC в CryptoJS

Подпись API-запросов

const secret = "api_secret";
const payload = JSON.stringify({
  userId: 42,
  action: "transfer"
});

const signature = CryptoJS.HmacSHA256(payload, secret).toString();

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

Проверка целостности данных

function verify(message, secret, expectedHash) {
  const computed = CryptoJS.HmacSHA512(message, secret).toString();
  return computed === expectedHash;
}

Защита webhook-запросов

const signature = CryptoJS.HmacSHA256(body, secret)
  .toString(CryptoJS.enc.Hex);

if (signature !== receivedSignature) {
  throw new Error("Invalid signature");
}

Внутренние особенности реализации CryptoJS

CryptoJS не использует нативные криптографические API браузера. Вся реализация HMAC построена на JavaScript, что приводит к следующим особенностям:

  • детерминированное поведение в любых средах
  • отсутствие зависимости от WebCrypto API
  • более медленная работа по сравнению с нативными реализациями
  • удобство в кросс-платформенных приложениях

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

Ключ в HMAC не требует сложной подготовки, но его качество напрямую влияет на безопасность.

Рекомендации по ключам:

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

Пример генерации ключа:

const key = CryptoJS.lib.WordArray.random(32);

Частые ошибки при использовании

Использование одинакового ключа в разных системах

Это приводит к компрометации всей схемы подписи при утечке одного сервиса.

Неправильное кодирование данных

CryptoJS.HmacSHA256("data", "key")

и

CryptoJS.HmacSHA256(CryptoJS.enc.Utf8.parse("data"), "key")

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

Сравнение строк без защиты от timing-attack

if (hash === signature) { }

Такие сравнения потенциально уязвимы при высоких требованиях к безопасности.

Интероперабельность с Node.js crypto

В Node.js аналог HMAC выглядит так:

import crypto from "crypto";

const hmac = crypto
  .createHmac("sha256", "secret")
  .update("message")
  .digest("hex");

Результаты совпадают с CryptoJS при корректной обработке кодировок.

Форматы входных данных

CryptoJS поддерживает несколько форматов:

  • строка (UTF-8 по умолчанию)
  • WordArray
  • Base64
  • Hex

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

Производственные сценарии использования

HMAC-SHA256 чаще применяется в:

  • REST API подписи
  • JWT-подобных системах
  • проверке webhook-уведомлений

HMAC-SHA512 используется в:

  • финансовых системах
  • криптографических протоколах повышенной надёжности
  • долгосрочном хранении подписанных данных