Отличие JWS от JWT

Базовая модель JWS

JWS (JSON Web Signature) представляет собой спецификацию, описывающую способ криптографического подписывания произвольного содержимого. Основная цель — обеспечить целостность данных и подтверждение подлинности отправителя без обязательного шифрования содержимого.

Структура JWS в компактной форме всегда состоит из трёх частей:

  • заголовок (JOSE Header)
  • полезная нагрузка (Payload)
  • подпись (Signature)

Каждая часть кодируется в Base64URL и разделяется точками:

BASE64URL(header).BASE64URL(payload).BASE64URL(signature)

Ключевая особенность JWS заключается в том, что payload не ограничен форматом JSON. Это может быть строка, бинарные данные или JSON — спецификация допускает произвольное содержимое.

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


JWT как частный случай JWS

JWT (JSON Web Token) — это прикладной формат, построенный поверх JWS. Его основное отличие заключается в строгом ограничении payload: он всегда является JSON-объектом, содержащим набор утверждений (claims).

Таким образом:

  • JWS — универсальный контейнер для подписанных данных
  • JWT — стандартизированный профиль JWS для передачи JSON-claims

JWT наследует структуру JWS, но накладывает дополнительные правила:

  • payload должен быть корректным JSON
  • используются стандартные наборы claims (iss, sub, exp, iat и другие)
  • предназначен преимущественно для авторизации и идентификации

Структурное отличие payload

На уровне структуры основное различие проявляется в содержимом payload.

JWS:

  • payload может быть любым
  • допускаются произвольные байты после кодирования

JWT:

  • payload строго JSON
  • содержит набор атрибутов с семантическим значением

Пример JWT payload:

{
  "sub": "1234567890",
  "name": "Ivan Ivanov",
  "admin": true,
  "iat": 1516239022
}

В JWS аналогичный payload мог бы быть строкой:

"raw-data-or-binary-stream"

или любым другим форматом без структурных требований.


Роль заголовка (Header)

И в JWS, и в JWT используется JOSE Header, содержащий метаинформацию о криптографических параметрах:

  • алгоритм подписи (alg)
  • тип токена (typ)
  • ключевой идентификатор (kid)

Пример:

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

Важно, что поле typ чаще всего используется именно в JWT-ориентированных сценариях. В JWS оно не является обязательным и не несёт семантической нагрузки.


Подпись и алгоритмы

Обе технологии используют одинаковый механизм подписи:

  • HMAC (HS256, HS512)
  • RSA (RS256, RS512)
  • ECDSA (ES256 и др.)

Разница не в криптографии, а в уровне абстракции применения.

JWS определяет только механизм формирования подписи:

sign(input = BASE64URL(header) + "." + BASE64URL(payload))

JWT добавляет семантику данных, но не меняет сам процесс подписи.


Jsrsasign: работа с JWS

В Jsrsasign базовые операции с JWS выполняются через API:

Генерация JWS

const sHeader = JSON.stringify({ alg: "HS256", typ: "JWS" });
const sPayload = "Hello World";

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

Здесь payload является обычной строкой, что демонстрирует универсальность JWS.


Проверка JWS

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

Проверка не зависит от структуры payload — она проверяет только целостность и корректность подписи.


Jsrsasign: работа с JWT

JWT в Jsrsasign реализуется как специализированный случай JWS:

const header = { alg: "HS256", typ: "JWT" };
const payload = {
  sub: "1234567890",
  name: "Ivan Ivanov",
  admin: true
};

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

Отличие заключается в том, что payload всегда сериализуется в JSON.


Семантическое различие назначения

JWS используется там, где требуется:

  • подписывать произвольные данные
  • обеспечивать целостность сообщений
  • работать с бинарными или нестандартизированными payload

JWT используется там, где требуется:

  • передача информации о пользователе
  • авторизация и аутентификация
  • обмен claims между сервисами

Проверка и извлечение данных

В Jsrsasign извлечение данных также отражает различие моделей.

JWS

const parsed = KJUR.jws.JWS.parse(jws);

Payload остаётся в исходном виде и требует ручной интерпретации.

JWT

const decoded = KJUR.jws.JWS.parse(jwt);
const payloadObj = JSON.parse(decoded.payloadPP);

JWT предполагает обязательное преобразование payload в объект.


Ошибки интерпретации JWT как отдельного стандарта

Частая концептуальная ошибка заключается в восприятии JWT как самостоятельного протокола. На уровне спецификаций JWT не существует вне JWS — это всего лишь профиль использования.

JWS определяет:

  • формат подписи
  • алгоритмы
  • структуру токена

JWT добавляет:

  • структуру JSON payload
  • стандартные claims
  • область применения (identity, access control)

Ключевые отличия на уровне модели данных

Характеристика JWS JWT
Тип payload произвольный JSON
Назначение универсальная подпись авторизационные токены
Стандартизация данных отсутствует обязательные claims
Область применения широкая ограниченная (identity/security)

Поведение в Jsrsasign при ошибках формата

При работе с Jsrsasign различие становится особенно заметным при валидации:

  • JWS успешно проверяется независимо от структуры payload
  • JWT может требовать корректного JSON для дальнейшей обработки приложением

Библиотека не навязывает строгую JWT-валидацию на уровне JWS API, что подчёркивает их иерархию: JWT — надстройка над JWS.


Практическое значение различий

В реальных системах выбор между JWS и JWT определяется не криптографией, а архитектурой:

  • JWS применяется для подписанных сообщений, файлов, запросов API
  • JWT применяется в системах идентификации и авторизации пользователей

Jsrsasign поддерживает оба сценария через единый криптографический слой, различая их только на уровне структуры данных и интерпретации payload