HMAC (Hash-based Message Authentication Code) строится поверх криптографической хеш-функции и используется для проверки целостности и подлинности сообщений. В библиотеке CryptoJS поддерживаются как одноразовые вычисления HMAC, так и прогрессивный (потоковый) режим, при котором данные поступают частями.
Прогрессивное вычисление особенно важно при работе с большими объёмами данных, потоками из сети, файлами или любыми источниками, где полное сообщение недоступно сразу.
HMAC основан на двух стадиях хеширования:
hash(key ⊕ ipad || message)hash(key ⊕ opad || inner_hash_result)где:
ipad — повторяющийся байт 0x36opad — повторяющийся байт 0x5c⊕ — побитовое XORCryptoJS реализует эту схему через алгоритмический конструктор
CryptoJS.algo.HMAC.
При однократном вычислении используется простая форма:
const hmac = CryptoJS.HmacSHA256("message", "secret");
Такой подход применим только когда данные уже полностью доступны в памяти.
Для потоковой обработки используется создание экземпляра HMAC:
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, "secret");
После создания объект поддерживает инкрементальное добавление данных.
При вызове create происходит подготовка:
Внутренний механизм эквивалентен следующей логике:
key ⊕ ipad → внутренний стартовый блок
key ⊕ opad → внешний блок
Основной метод прогрессивного режима — update.
hmac.update("first chunk");
hmac.update("second chunk");
hmac.update("third chunk");
Каждый вызов:
Ключевая особенность: состояние хеша не сбрасывается между вызовами.
SHA-256 внутри CryptoJS работает на уровне 512-битных блоков.
При поступлении данных:
данные накапливаются в WordArray
когда размер ≥ 512 бит:
промежуточное состояние сохраняется
Это позволяет обрабатывать поток без хранения полного сообщения.
После передачи всех частей вызывается:
const result = hmac.finalize();
На этом этапе выполняются:
Результат возвращается как WordArray.
const hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, "secret-key");
hmac.update("chunk-1");
hmac.update("chunk-2");
hmac.update("chunk-3");
const digest = hmac.finalize();
console.log(digest.toString(CryptoJS.enc.Hex));
Одноразовый режим:
Прогрессивный режим:
CryptoJS оперирует объектом WordArray, поэтому данные
могут поступать не только строками:
hmac.update(CryptoJS.enc.Hex.parse("deadbeef"));
hmac.update(CryptoJS.lib.WordArray.create([0x12345678]));
Это важно при работе с:
Ключ проходит нормализацию:
Это обеспечивает устойчивость к атаке на длину ключа.
Объект HMAC в CryptoJS можно рассматривать как конечный автомат:
INIT
INNER UPDATE
INNER FINALIZE
OUTER HASH
DONE
После вызова finalize объект считается завершённым.
Для нового сообщения требуется создание нового экземпляра:
const hmac1 = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
hmac1.update("data").finalize();
const hmac2 = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
hmac2.update("other").finalize();
Прогрессивное HMAC используется в:
HMAC можно строить поверх любых хеш-функций CryptoJS:
CryptoJS.algo.HMAC.create(CryptoJS.algo.MD5, key);
CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, key);
CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, key);
Выбор алгоритма влияет на:
Результат HMAC — это WordArray, который может быть
преобразован:
digest.toString(CryptoJS.enc.Hex);
digest.toString(CryptoJS.enc.Base64);
Прогрессивная модель снижает:
Особенно заметно при обработке данных > десятков мегабайт.
Если входные данные не кратны размеру блока:
updatefinalize| Тип данных | Поведение |
|---|---|
| строка | UTF-8 преобразование |
| WordArray | прямое использование |
| hex/base64 | декодирование через enc |
Прогрессивное вычисление HMAC в CryptoJS демонстрирует классическую потоковую модель:
Эта модель соответствует требованиям криптографических протоколов, где данные поступают частями и не могут быть агрегированы заранее.