HMAC (Hash-based Message Authentication Code) в Stanford JavaScript Crypto Library (SJCL) реализуется как надстройка над криптографическими хэш-функциями и используется для проверки целостности и подлинности данных. В основе лежит комбинация секретного ключа и выбранной хэш-функции, что делает подделку сообщения без знания ключа вычислительно неосуществимой задачей.
В SJCL HMAC реализован через sjcl.misc.hmac, который
принимает в качестве параметров ключ и класс хэш-функции.
Создание HMAC-объекта в SJCL выполняется следующим образом:
var hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
Здесь:
key — секретный ключ (в формате
bitArray)sjcl.hash.sha256 — используемая хэш-функцияКлюч может быть задан в разных форматах, но чаще всего используется преобразование строки:
var key = sjcl.codec.utf8String.toBits("secret-key");
После создания объекта HMAC можно вычислять MAC для любых данных:
var data = "Сообщение для проверки";
var dataBits = sjcl.codec.utf8String.toBits(data);
var mac = hmac.encrypt(dataBits);
var macHex = sjcl.codec.hex.fromBits(mac);
Результат mac — это bitArray, который можно
преобразовать в hex, base64 или другие форматы через
sjcl.codec.
SJCL поддерживает несколько криптографических хэш-функций, которые можно использовать внутри HMAC. Наиболее распространённые:
sjcl.hash.sha1sjcl.hash.sha256sjcl.hash.sha512Выбор хэш-функции напрямую влияет на уровень безопасности и производительность.
SHA-1 считается устаревшим с точки зрения криптографической стойкости, но может использоваться в совместимости с легаси-системами.
var key = sjcl.codec.utf8String.toBits("key");
var hmacSha1 = new sjcl.misc.hmac(key, sjcl.hash.sha1);
var msg = sjcl.codec.utf8String.toBits("data");
var mac = hmacSha1.encrypt(msg);
console.log(sjcl.codec.hex.fromBits(mac));
Особенности:
SHA-256 является стандартом де-факто для большинства современных приложений.
var key = sjcl.codec.utf8String.toBits("secure-key");
var hmacSha256 = new sjcl.misc.hmac(key, sjcl.hash.sha256);
var msg = sjcl.codec.utf8String.toBits("important message");
var mac = hmacSha256.encrypt(msg);
var macBase64 = sjcl.codec.base64.fromBits(mac);
Преимущества:
SHA-512 обеспечивает ещё более высокий уровень стойкости, особенно при работе на 64-битных архитектурах.
var key = sjcl.codec.utf8String.toBits("very-secure-key");
var hmacSha512 = new sjcl.misc.hmac(key, sjcl.hash.sha512);
var msg = sjcl.codec.utf8String.toBits("sensitive data");
var mac = hmacSha512.encrypt(msg);
console.log(sjcl.codec.hex.fromBits(mac));
Особенности:
SJCL работает с внутренним типом bitArray, поэтому все
входные данные требуют преобразования.
sjcl.codec.utf8String.toBits("text");
sjcl.codec.hex.toBits("deadbeef");
sjcl.codec.base64.toBits("SGVsbG8=");
Часто HMAC используется для проверки целостности:
var expectedMac = hmac.encrypt(dataBits);
var receivedMac = sjcl.codec.hex.toBits("...");
var valid = sjcl.bitArray.equal(expectedMac, receivedMac);
Функция sjcl.bitArray.equal обеспечивает корректное
сравнение массивов битов.
// неправильно
hmac.encrypt("text");
// правильно
hmac.encrypt(sjcl.codec.utf8String.toBits("text"));
HMAC предполагает, что ключ остаётся секретным. Его повторное использование в разных доменах без изоляции может привести к утечкам через побочные каналы.
Использование SHA-1 в новых системах снижает безопасность, даже если HMAC в целом остаётся устойчивым.
var key = sjcl.codec.utf8String.toBits("api-secret");
var hmac = new sjcl.misc.hmac(key, sjcl.hash.sha256);
function signMessage(message) {
var bits = sjcl.codec.utf8String.toBits(message);
return sjcl.codec.hex.fromBits(hmac.encrypt(bits));
}
function verifyMessage(message, signature) {
var bits = sjcl.codec.utf8String.toBits(message);
var expected = hmac.encrypt(bits);
var received = sjcl.codec.hex.toBits(signature);
return sjcl.bitArray.equal(expected, received);
}
SJCL реализует HMAC поверх стандартных хэш-функций без аппаратного ускорения, что означает:
Хэш-функция является основным фактором производительности: SHA-512 обычно медленнее SHA-256 в JS-средах.
HMAC в SJCL часто используется как базовый строительный блок для:
Типичная схема:
Ключ в SJCL представлен как bitArray, но его
безопасность зависит от хранения:
var key = sjcl.codec.utf8String.toBits(generateSecret());
SJCL позволяет использовать HMAC не только для строк, но и для произвольных бинарных данных:
var fileBits = sjcl.codec.hex.toBits(binaryHexData);
var mac = hmac.encrypt(fileBits);
Это важно при: