HS256, HS384 и HS512 относятся к семейству HMAC-алгоритмов, основанных на SHA-хэшировании. В контексте JSON Web Token (JWT) и библиотеки Jsrsasign они используются для симметричного подписывания и проверки токенов, где один и тот же секрет применяется как для генерации подписи, так и для её верификации.
HMAC (Hash-based Message Authentication Code) представляет собой механизм, обеспечивающий целостность и подлинность данных с использованием криптографической хэш-функции и секретного ключа.
В Jsrsasign алгоритмы HS256, HS384 и HS512 реализуются через SHA-2 семейство:
Ключевой особенностью является симметричность: секрет одинаково используется на стороне подписания и проверки.
HS256 является наиболее часто используемым вариантом в JWT благодаря балансу между производительностью и криптографической стойкостью.
В Jsrsasign работа с HS256 обычно строится через пространство имён
KJUR.jws.JWS.
Пример создания JWT:
const header = {
alg: "HS256",
typ: "JWT"
};
const payload = {
sub: "user123",
name: "Ivan Petrov",
admin: true,
iat: Math.floor(Date.now() / 1000)
};
const secret = "my-secret-key";
const token = KJUR.jws.JWS.sign(
"HS256",
JSON.stringify(header),
JSON.stringify(payload),
secret
);
В этом процессе:
Верификация токена выполняется тем же секретом:
const isValid = KJUR.jws.JWS.verify(token, secret, ["HS256"]);
Параметр массива алгоритмов позволяет ограничить допустимые схемы подписи.
Если подпись корректна, результат будет true, иначе
false.
HS384 использует SHA-384, что увеличивает длину хэш-выхода и повышает устойчивость к коллизиям.
Создание JWT:
const token = KJUR.jws.JWS.sign(
"HS384",
JSON.stringify(header),
JSON.stringify(payload),
secret
);
Проверка:
const isValid = KJUR.jws.JWS.verify(token, secret, ["HS384"]);
HS384 применяется в системах, где требуется повышенный уровень криптографической устойчивости без перехода на асимметричные алгоритмы.
HS512 использует SHA-512 и обеспечивает наиболее длинный хэш среди HMAC-вариантов JWT.
Подписание:
const token = KJUR.jws.JWS.sign(
"HS512",
JSON.stringify(header),
JSON.stringify(payload),
secret
);
Проверка:
const isValid = KJUR.jws.JWS.verify(token, secret, ["HS512"]);
Использование HS512 увеличивает вычислительную нагрузку, но обеспечивает более высокий уровень защиты от атак перебора и коллизий.
JWT в Jsrsasign состоит из трёх частей:
header.payload.signature
Каждая часть кодируется в Base64URL.
Библиотека автоматически:
Для ручного анализа можно декодировать токен:
const decoded = KJUR.jws.JWS.parse(token);
console.log(decoded.headerObj);
console.log(decoded.payloadObj);
В Jsrsasign выбор алгоритма определяется балансом между:
HS256:
HS384:
HS512:
Jsrsasign не выбрасывает исключение при невалидной подписи, вместо
этого возвращается false. Однако при некорректной структуре
токена возможны исключения.
Пример безопасной проверки:
try {
const result = KJUR.jws.JWS.verify(token, secret, ["HS256", "HS384", "HS512"]);
if (result) {
// токен валиден
} else {
// подпись не совпадает
}
} catch (e) {
// повреждённый или некорректный токен
}
Jsrsasign позволяет указывать набор допустимых алгоритмов:
const isValid = KJUR.jws.JWS.verify(token, secret, [
"HS256",
"HS384"
]);
Это полезно при миграции систем, когда старые токены подписаны одним алгоритмом, а новые другим.
При использовании HS256/384/512 важно учитывать:
Jsrsasign не управляет безопасностью ключей — это зона ответственности приложения.
Пример генерации случайного ключа:
const secret = KJUR.crypto.Util.getRandomHexOfNbytes(32);
Для HS512 рекомендуется использовать не менее 512 бит (64 байта) энтропии.
Низкоуровневый API позволяет более гибко управлять процессом:
const sHeader = JSON.stringify({ alg: "HS256", typ: "JWT" });
const sPayload = JSON.stringify({ data: "test" });
const jws = new KJUR.jws.JWS();
const signed = jws.sign(
"HS256",
sHeader,
sPayload,
secret
);
Этот подход используется в более сложных сценариях, где требуется контроль над этапами формирования JWT.
Каждый из этих случаев приводит к невалидной подписи или ошибке проверки.
Jsrsasign реализован на чистом JavaScript и одинаково работает:
Алгоритмы HS256/384/512 не зависят от криптографических API платформы, так как реализованы внутри библиотеки через JavaScript-хэширование.