Compact Serialization

Компактная сериализация в контексте JWS (JSON Web Signature) представляет собой строго определённый способ представления подписанного сообщения в виде одной строки. В библиотеке Jsrsasign этот формат используется для создания и проверки JWT и JWS без промежуточных структур JSON в передаче.

Строка компактной сериализации состоит из трёх частей:

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

Каждая часть кодируется по правилам Base64URL без использования символов = в конце и без переносов строк.

Структура имеет фиксированное количество сегментов, разделённых точками:

  • заголовок (header)
  • полезная нагрузка (payload)
  • подпись (signature)

Любое отклонение от этого формата делает строку невалидной с точки зрения спецификации JWS.


Base64URL кодирование и его роль

В Jsrsasign используется модифицированное Base64-кодирование, известное как Base64URL. Оно отличается от стандартного Base64 следующими моментами:

  • символ + заменяется на -
  • символ / заменяется на _
  • отсутствует padding =

Это необходимо для безопасного использования в URL, HTTP заголовках и JSON без дополнительного экранирования.

Пример преобразования:

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

после сериализации и кодирования превращается в:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Формирование структуры JWS Compact Serialization

Процесс формирования компактной строки в Jsrsasign включает последовательные этапы:

  1. Формирование JSON заголовка с параметрами алгоритма подписи
  2. Формирование JSON полезной нагрузки
  3. Кодирование обеих частей в Base64URL
  4. Вычисление криптографической подписи
  5. Кодирование подписи в Base64URL
  6. Объединение всех частей через точку

Пример структуры:

header.payload.signature

Каждая часть является независимым элементом, но логически связана с другими.


Создание JWS в Jsrsasign

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

Типичный процесс генерации подписи:

const header = { alg: "HS256", typ: "JWT" };
const payload = { sub: "1234567890", name: "John Doe", admin: true };
const secret = "your-256-bit-secret";

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

Результатом является строка компактной сериализации.


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

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

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

Процесс проверки включает:

  • разбиение строки на три части
  • декодирование header и payload
  • пересчёт подписи
  • сравнение полученной подписи с переданной

Несовпадение любой части приводит к отрицательному результату проверки.


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

JWT (JSON Web Token) фактически является частным случаем JWS, использующим компактную сериализацию.

JWT всегда имеет три сегмента:

  • Header
  • Payload
  • Signature

Payload JWT обычно содержит стандартные поля:

  • iss (issuer)
  • sub (subject)
  • exp (expiration time)
  • iat (issued at)

Пример полезной нагрузки:

{
  "iss": "auth-server",
  "sub": "user123",
  "exp": 1710000000
}

После сериализации JWT не отличается по структуре от JWS Compact Serialization.


Алгоритмы подписи в Jsrsasign

Jsrsasign поддерживает несколько алгоритмов, используемых в компактной сериализации:

  • HS256, HS384, HS512 (HMAC)
  • RS256, RS384, RS512 (RSA)
  • ES256, ES384, ES512 (ECDSA)

Выбор алгоритма определяется полем alg в заголовке:

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

Алгоритм определяет способ формирования signature segment.


Особенности формирования подписи

Подпись создаётся на основе строки:

BASE64URL(header) + "." + BASE64URL(payload)

Эта строка называется signing input.

Криптографическая функция применяется именно к этому значению, а не к исходному JSON.

Для алгоритма HS256 используется HMAC-SHA256:

HMACSHA256(secret, signing_input)

Для RSA:

RSASSA-PKCS1-v1_5(SHA-256, private_key, signing_input)

Разбор компактной строки

Jsrsasign позволяет вручную разбирать JWS:

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

Результат содержит:

  • headerObj
  • payloadObj
  • signatureHex
  • signingInput

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


Ошибки при работе с Compact Serialization

На практике часто возникают следующие проблемы:

Нарушение Base64URL формата

Использование стандартного Base64 с = приводит к невозможности корректной верификации.


Несоответствие алгоритма

Если alg в header не совпадает с используемым при проверке, подпись считается недействительной.


Изменение payload после подписи

Любое изменение даже одного символа в payload приводит к полной невалидности подписи.


Ошибки кодировки JSON

Различия в порядке ключей JSON могут влиять на строку подписи, если используется ручная сериализация.


JWE Compact Serialization (расширенная модель)

В отличие от JWS, JWE (JSON Web Encryption) использует компактную сериализацию из пяти частей:

header.encryptedKey.iv.ciphertext.authTag

В Jsrsasign шифрование выполняется через:

const jwe = KJUR.jwe.JWE.encrypt(plainText, publicKey, { alg: "RSA-OAEP", enc: "A256GCM" });

Каждый сегмент также кодируется в Base64URL, но структура более сложная и ориентирована на конфиденциальность данных, а не только на целостность.


Внутренние механизмы обработки строк

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

  • разбиение строки по символу .
  • декодирование Base64URL сегментов
  • преобразование JSON строк в объекты
  • криптографические вычисления через встроенные реализации SHA, RSA или ECDSA

Вся цепочка операций строго детерминирована, что обеспечивает совместимость с другими JWT/JWS реализациями.


Особенности использования в браузере и Node.js

Jsrsasign является универсальной библиотекой и работает как в браузере, так и в Node.js среде.

В браузере используются встроенные Web Crypto API или JavaScript-реализации криптографических алгоритмов.

В Node.js возможна интеграция с нативными криптографическими модулями, что ускоряет операции подписи и проверки.


Совместимость со стандартами RFC

Compact Serialization в Jsrsasign соответствует следующим стандартам:

  • RFC 7515 (JWS)
  • RFC 7519 (JWT)
  • RFC 7516 (JWE)

Соблюдение этих стандартов гарантирует совместимость токенов между различными библиотеками и сервисами авторизации.