Модуль jws

Модуль JWS в библиотеке jsrsasign реализует работу с JSON Web Signature — форматом цифровой подписи, стандартизированным в RFC 7515. Основная задача — формирование, подпись и проверка токенов, состоящих из трех частей:

BASE64URL(HEADER) . BASE64URL(PAYLOAD) . BASE64URL(SIGNATURE)

Внутренняя структура модуля организована вокруг пространства имен KJUR.jws, где ключевые операции разделены на генерацию подписи и её верификацию.


Структура JWS

JWS состоит из следующих компонентов:

Заголовок (Header)

JSON-объект с метаданными подписи:

{
  "alg": "HS256",
  "typ": "JWT"
}

Ключевые поля:

  • alg — алгоритм подписи (например, HS256, RS256, ES256)
  • typ — тип токена (обычно JWT)
  • kid — идентификатор ключа

Полезная нагрузка (Payload)

Произвольный JSON:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022
}

Подпись (Signature)

Результат криптографической операции:

HMACSHA256(
  base64UrlEncode(header) + "." + base64UrlEncode(payload),
  secret
)

Пространство имен KJUR.jws

Основные классы и методы:

KJUR.jws.JWS

Главный класс для работы с подписью.

Генерация подписи

var sHeader = JSON.stringify({alg: "HS256", typ: "JWT"});
var sPayload = JSON.stringify({user: "alice"});

var sJWS = KJUR.jws.JWS.sign(
  "HS256",
  sHeader,
  sPayload,
  "secret"
);

Параметры:

  • алгоритм (HS256, RS256, и т.д.)
  • строка заголовка
  • строка payload
  • ключ (секрет или приватный ключ)

Проверка подписи

var isValid = KJUR.jws.JWS.verify(
  sJWS,
  "secret",
  ["HS256"]
);

Возвращает true или false.


Поддерживаемые алгоритмы

HMAC (симметричные)

  • HS256
  • HS384
  • HS512

RSA (асимметричные)

  • RS256
  • RS384
  • RS512

ECDSA

  • ES256
  • ES384
  • ES512

Алгоритмы соответствуют стандартам из RFC 7518.


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

Генерация ключа

var keypair = KEYUTIL.generateKeypair("RSA", 2048);

Подпись

var sJWS = KJUR.jws.JWS.sign(
  "RS256",
  sHeader,
  sPayload,
  keypair.prvKeyObj
);

Проверка

var isValid = KJUR.jws.JWS.verify(
  sJWS,
  keypair.pubKeyObj,
  ["RS256"]
);

Работа с ECDSA

var keypair = KEYUTIL.generateKeypair("EC", "secp256r1");

Поддерживаемые кривые:

  • P-256
  • P-384
  • P-521

Base64URL кодирование

JWS использует Base64URL, отличающийся от стандартного Base64:

Символ Base64 Base64URL
+ + -
/ / _
= padding удаляется

В jsrsasign:

var encoded = KJUR.jws.JWS.readSafeJSONString(sJWS);

Разбор JWS

var parsed = KJUR.jws.JWS.parse(sJWS);

Результат:

{
  headerObj: {...},
  payloadObj: {...},
  sigHex: "..."
}

Работа с JWT

JWS лежит в основе JWT. Модуль позволяет работать с JWT напрямую:

var isValid = KJUR.jws.JWS.verifyJWT(
  token,
  key,
  {
    alg: ["HS256"],
    iss: ["issuer"],
    aud: ["audience"]
  }
);

Параметры проверки:

  • alg — допустимые алгоритмы
  • iss — issuer
  • aud — audience
  • exp — время истечения
  • nbf — not before

Проверка временных параметров

JWS.verifyJWT автоматически проверяет:

  • exp — срок действия
  • nbf — время начала действия
  • iat — время выпуска

Пример payload:

{
  "exp": 1716239022,
  "nbf": 1616239022
}

Использование секретов и ключей

Тип ключа зависит от алгоритма:

Алгоритм Тип ключа
HS256 строка (secret)
RS256 RSA ключ
ES256 EC ключ

Ключи могут быть:

  • PEM
  • HEX
  • объект jsrsasign

Работа с PEM

var pubKey = KEYUTIL.getKey(pemString);

PEM формат:

-----BEGIN PUBLIC KEY-----
...
-----END PUBLIC KEY-----

Обработка ошибок

Методы могут выбрасывать исключения:

  • некорректный формат JWS
  • неподдерживаемый алгоритм
  • неверная подпись

Рекомендуется использовать try/catch:

try {
  var isValid = KJUR.jws.JWS.verify(sJWS, key, ["RS256"]);
} catch (e) {
  console.error(e);
}

Безопасность

Критические аспекты

  • запрещение алгоритма none
  • строгая проверка списка допустимых алгоритмов
  • проверка aud, iss

Пример уязвимости: если не ограничить алгоритмы:

verify(token, key)

возможно подменить alg на none.


Оптимизация

  • кеширование ключей
  • повторное использование объектов ключей
  • минимизация парсинга JSON

Внутренние механизмы

Модуль использует:

  • KJUR.crypto.Signature
  • KEYUTIL
  • ASN1 обработчики

Подпись формируется так:

  1. кодирование header и payload
  2. конкатенация через .
  3. хеширование
  4. подпись ключом

Практический пример полного цикла

var header = {alg: "HS256", typ: "JWT"};
var payload = {user: "admin"};

var token = KJUR.jws.JWS.sign(
  "HS256",
  JSON.stringify(header),
  JSON.stringify(payload),
  "secret"
);

var valid = KJUR.jws.JWS.verify(token, "secret", ["HS256"]);

Расширенные возможности

  • поддержка нестандартных заголовков
  • работа с kid
  • интеграция с JWK

Поддержка JWK

var key = KEYUTIL.getKey({
  kty: "RSA",
  n: "...",
  e: "AQAB"
});

Ограничения

  • отсутствие встроенной поддержки JWE (шифрования)
  • необходимость ручной проверки бизнес-логики

Связь с другими стандартами

JWS используется в:

  • OAuth 2.0
  • OpenID Connect

Рекомендации по применению

  • использовать RS256 вместо HS256 в распределённых системах
  • хранить приватные ключи вне кода
  • валидировать все поля токена
  • избегать длинных payload

Диагностика

Полезные методы:

KJUR.jws.JWS.parse(token)

Позволяет анализировать содержимое без проверки подписи.


Заключительная структура JWS

HEADER  -> алгоритм и метаданные
PAYLOAD -> данные
SIGNATURE -> криптографическая подпись

Модуль JWS в jsrsasign обеспечивает полный цикл работы с цифровыми подписями в формате, совместимом с современными протоколами аутентификации и авторизации.