JSON Serialization

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

В библиотеке Jsrsasign работа с JSON-сериализацией встроена в модуль KJUR.jws, который реализует спецификации JWS и JWT, включая поддержку форматов General JSON Serialization и Flattened JSON Serialization.


Структура JSON-сериализации JWS

JSON-сериализация JWS существует в двух формах:

Flattened JSON Serialization

Используется для одного подписанта. Структура объекта:

  • payload — полезная нагрузка (Base64URL или JSON)
  • protected — защищённый заголовок (Base64URL encoded JSON)
  • header — незашифрованный заголовок (необязателен)
  • signature — криптографическая подпись

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

{
  "protected": "eyJhbGciOiJIUzI1NiJ9",
  "payload": "eyJ1c2VySWQiOjEyM30",
  "signature": "abc123..."
}

General JSON Serialization

Используется для множественных подписей. Отличие заключается в наличии массива signatures.

Структура:

  • payload — общие данные
  • signatures[] — массив объектов подписей

Каждый элемент signatures содержит:

  • protected
  • header
  • signature

Пример:

{
  "payload": "eyJ1c2VySWQiOjEyM30",
  "signatures": [
    {
      "protected": "eyJhbGciOiJSUzI1NiJ9",
      "signature": "sig1..."
    },
    {
      "protected": "eyJhbGciOiJFUzI1NiJ9",
      "signature": "sig2..."
    }
  ]
}

JSON Web Signature в Jsrsasign

Библиотека Jsrsasign предоставляет функциональность генерации и проверки JWS через объект KJUR.jws.JWS.

Основные операции:

  • создание подписи
  • проверка подписи
  • разбор структуры JWS
  • работа с JSON Serialization

Создание JWS в JSON Serialization

Хотя чаще используется компактный формат, Jsrsasign поддерживает генерацию JSON-структур через расширенные API.

Пример генерации JWS:

const header = {
  alg: "HS256",
  typ: "JWT"
};

const payload = {
  sub: "1234567890",
  name: "Alice",
  admin: true
};

const key = "secret";

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

В случае JSON Serialization структура формируется не строкой, а объектом, где результат раскладывается по полям protected, payload, signature.


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

JSON Serialization в JWS использует Base64URL кодирование без padding:

  • + заменяется на -
  • / заменяется на _
  • = удаляется

Это критически важно, так как любая ошибка в кодировании приводит к невозможности верификации подписи.

Jsrsasign автоматически обрабатывает Base64URL преобразование внутри функций KJUR.jws.


Protected и Unprotected заголовки

Protected Header

Закодированный JSON, который участвует в вычислении подписи. Любое изменение приводит к инвалидности подписи.

Пример:

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

После кодирования:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Unprotected Header

Передаётся в открытом виде и не влияет на подпись. Используется для метаданных, которые могут изменяться без нарушения криптографической целостности.


Механизм формирования подписи

Процесс формирования JWS JSON Serialization включает несколько шагов:

  1. Формирование JSON заголовка
  2. Кодирование header в Base64URL
  3. Кодирование payload в Base64URL
  4. Конкатенация:
BASE64URL(protected) + "." + BASE64URL(payload)
  1. Вычисление HMAC или RSA/ECDSA подписи
  2. Кодирование подписи в Base64URL
  3. Формирование JSON объекта

Пример: Flattened JSON JWS

const jwsObj = KJUR.jws.JWS.sign(
  "HS256",
  JSON.stringify({ alg: "HS256" }),
  JSON.stringify({ message: "data" }),
  "secret"
);

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

Результат jwsObj в JSON-формате может быть преобразован в структуру:

{
  "protected": "...",
  "payload": "...",
  "signature": "..."
}

Разбор JSON JWS

Для анализа структуры используется:

const result = KJUR.jws.JWS.parse(jwsString);

Возвращаемый объект содержит:

  • headerObj
  • payloadObj
  • sigval
  • headerB64U

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

Проверка выполняется через:

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

В случае JSON Serialization библиотека автоматически извлекает:

  • protected header
  • payload
  • signature

и выполняет проверку согласно алгоритму alg.


Множественные подписи (General JSON Serialization)

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

Каждая подпись может использовать собственный алгоритм:

  • HS256
  • RS256
  • ES256

Пример логики:

  • один payload
  • несколько независимых подписей
  • независимые ключи

Это используется в сценариях:

  • распределённая валидация
  • мульти-организационные подписи
  • аудит данных

Каноникализация JSON

При работе с JSON Serialization важно учитывать, что JSON должен быть канонизирован перед подписью.

Ключевые требования:

  • отсутствие лишних пробелов
  • стабильный порядок ключей (в некоторых реализациях)
  • строгое UTF-8 кодирование

Jsrsasign минимизирует проблемы каноникализации за счёт внутренней обработки строк, однако при передаче объектов через JSON.stringify порядок ключей может влиять на воспроизводимость подписи в сложных системах.


Особенности реализации Jsrsasign

Внутренне библиотека:

  • использует CryptoJS или WebCrypto (в зависимости от окружения)
  • поддерживает синхронные операции подписи
  • реализует Base64URL без сторонних зависимостей
  • поддерживает JWT поверх JWS

Модули:

  • KJUR.jws.JWS
  • KJUR.jws.IntDate
  • KJUR.jws.JWSJS (в некоторых версиях для JSON serialization helpers)

JWT и JSON Serialization

JWT (JSON Web Token) является частным случаем JWS, где payload — JSON объект с claims.

JSON Serialization особенно полезна при:

  • расширенных JWT структурах
  • наличии дополнительных метаданных
  • необходимости мультиподписей

Стандартный JWT чаще использует Compact Serialization, однако JSON формат применяется в системах, где требуется явная структура и расширяемость.


Типичные ошибки при работе с JSON Serialization

  • использование обычного Base64 вместо Base64URL
  • изменение payload после подписи
  • несоответствие алгоритма alg и ключа
  • неконсистентный JSON перед подписью
  • потеря protected header при сериализации

Расширенные сценарии использования

JSON Serialization в Jsrsasign применяется в системах:

  • распределённой аутентификации
  • банковских API с мульти-подписью
  • блокчейн-ориентированных структурах подписи данных
  • протоколах с аудитом изменений

Структурированный формат позволяет добавлять дополнительные подписи без изменения исходного payload, что невозможно в compact-формате.