HMAC (Hash-based Message Authentication Code) представляет собой механизм проверки целостности и подлинности сообщений, основанный на криптографических хеш-функциях и секретном ключе. В контексте JavaScript-библиотеки CryptoJS реализация HMAC с алгоритмом SHA1 используется для создания подписи данных, которая позволяет убедиться, что сообщение не было изменено и действительно отправлено владельцем секретного ключа.
HMAC строится поверх хеш-функции SHA1 и секретного ключа. В отличие от обычного хеширования, где результат зависит только от входных данных, здесь добавляется ключевой компонент, который делает невозможным подделку подписи без знания секрета.
Основная схема вычисления выглядит следующим образом:
Ключевая идея заключается в том, что даже незначительное изменение входных данных или отсутствие ключа полностью изменяет итоговый хеш.
В библиотеке CryptoJS HMAC-SHA1 реализуется через функцию
CryptoJS.HmacSHA1.
Простейший пример формирования подписи:
const CryptoJS = require("crypto-js");
const message = "Hello, world";
const secretKey = "super_secret_key";
const hash = CryptoJS.HmacSHA1(message, secretKey).toString();
console.log(hash);
В этом примере:
message — данные, которые необходимо подписать;secretKey — секретный ключ, известный только
отправителю и получателю;CryptoJS позволяет получать результат HMAC-SHA1 в разных форматах. Это важно при интеграции с внешними API, где формат подписи строго регламентирован.
CryptoJS.HmacSHA1("data", "key").toString();
CryptoJS.HmacSHA1("data", "key").toString(CryptoJS.enc.Base64);
const result = CryptoJS.HmacSHA1("data", "key");
WordArray может использоваться для дальнейших криптографических операций без преобразования в строку.
HMAC-SHA1 может применяться не только к строкам, но и к бинарным данным. В CryptoJS это реализуется через encoders.
const data = CryptoJS.enc.Utf8.parse("binary safe message");
const key = CryptoJS.enc.Utf8.parse("secret");
const hash = CryptoJS.HmacSHA1(data, key).toString();
Такой подход исключает ошибки кодировки и позволяет корректно работать с любыми типами входных данных.
HMAC-SHA1 часто используется в системах аутентификации API-запросов. Суть заключается в том, что клиент формирует подпись запроса, а сервер проверяет её с помощью того же секретного ключа.
Пример формирования подписи запроса:
const CryptoJS = require("crypto-js");
function generateSignature(method, url, body, secret) {
const payload = method + url + body;
return CryptoJS.HmacSHA1(payload, secret).toString();
}
const signature = generateSignature(
"POST",
"/api/v1/order",
JSON.stringify({ price: 100 }),
"my_secret_key"
);
Подпись обычно передаётся в заголовках HTTP-запроса:
Authorization: HMAC-SHA1 <signature>
Несмотря на то, что SHA1 считается криптографически устаревшим для некоторых задач, в HMAC он остаётся допустимым в ряде систем благодаря структуре конструкции HMAC, которая компенсирует часть слабостей хеш-функции.
Важно учитывать:
Любая разница во входных данных приводит к полностью другому результату HMAC:
CryptoJS.HmacSHA1("data", "key").toString();
CryptoJS.HmacSHA1("Data", "key").toString();
Даже изменение регистра символов влияет на итоговый хеш, что подчёркивает чувствительность алгоритма.
Если строка создаётся из разных источников, возможны расхождения в кодировке:
CryptoJS.HmacSHA1("текст", "ключ");
В таких случаях рекомендуется явно задавать UTF-8:
CryptoJS.HmacSHA1(
CryptoJS.enc.Utf8.parse("текст"),
CryptoJS.enc.Utf8.parse("ключ")
);
Объекты JavaScript необходимо сериализовать:
const payload = JSON.stringify({ a: 1, b: 2 });
CryptoJS.HmacSHA1(payload, "key");
Прямая передача объекта приведёт к некорректному результату.
CryptoJS может использоваться и на клиентской стороне. Это удобно для предварительной генерации подписи перед отправкой запроса:
<script src="crypto-js.js"></script>
<script>
const signature = CryptoJS.HmacSHA1("message", "key").toString();
console.log(signature);
</script>
Важно учитывать, что размещение секретного ключа на клиенте снижает безопасность и допустимо только в ограниченных сценариях.
HMAC-SHA1 в CryptoJS реализован на JavaScript и не использует нативные ускорения, поэтому:
HMAC-SHA1 можно комбинировать с другими криптографическими операциями:
const step1 = CryptoJS.SHA1("data");
const signature = CryptoJS.HmacSHA1(step1, "key").toString();
Такие конструкции применяются в кастомных протоколах защиты данных.
HMAC-SHA1 в CryptoJS полностью совместим со стандартом RFC 2104. Это позволяет использовать его для взаимодействия с:
Особенно важно, что результат совпадает с реализациями на Java, Python, PHP и других языках при одинаковых входных данных и ключе.
CryptoJS работает через структуру WordArray, где данные представлены в виде 32-битных слов. Это влияет на:
Пример извлечения байтового представления:
const hmac = CryptoJS.HmacSHA1("data", "key");
console.log(hmac.words);
Такой формат используется внутри библиотеки до финального преобразования в строку.
HMAC-SHA1 применяется в:
Каждый из этих сценариев опирается на одно свойство: невозможность подделки подписи без знания секретного ключа.