Формат JWK: структура и поля

JWK (JSON Web Key) представляет собой стандартизированное JSON-представление криптографического ключа. В экосистеме JavaScript и библиотеки Jsrsasign JWK используется для обмена ключами между сервисами, хранения публичных и приватных ключей в структурированном виде и интеграции с JWT, JWS и JWE.

Основная идея JWK заключается в том, чтобы описывать ключ не в бинарной форме (как PEM или DER), а в виде JSON-объекта, пригодного для передачи по HTTP, хранения в конфигурациях и использования в веб-приложениях.


Базовая структура JWK

JWK всегда представляет собой JSON-объект с набором обязательных и дополнительных полей. Минимальная структура зависит от типа ключа, но общий шаблон выглядит следующим образом:

{
  "kty": "RSA",
  "kid": "key-id-123",
  "use": "sig",
  "alg": "RS256"
}

Каждое поле имеет строго определённое назначение и влияет на то, как ключ будет использоваться в криптографических операциях.


Поле kty (Key Type)

kty — обязательное поле, определяющее тип криптографического ключа.

Наиболее распространённые значения:

  • RSA — асимметричные RSA ключи
  • EC — эллиптические кривые
  • oct — симметричные ключи (HMAC, AES)

Пример:

{
  "kty": "EC"
}

Значение kty определяет набор обязательных параметров, которые должны присутствовать в объекте JWK. Например, для RSA требуются n и e, а для EC — crv, x, y.


Поле kid (Key ID)

kid — идентификатор ключа. Используется для выбора конкретного ключа из набора (JWKS).

{
  "kid": "auth-key-2026-01"
}

В системах с ротацией ключей kid играет ключевую роль: он позволяет серверу выбрать правильный публичный ключ для проверки подписи JWT.


Поле use (Key Use)

use определяет назначение ключа:

  • sig — для подписи и проверки подписи
  • enc — для шифрования
{
  "use": "sig"
}

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


Поле alg (Algorithm)

alg задаёт алгоритм, с которым ключ предназначен работать.

Примеры:

  • RS256 — RSA + SHA-256
  • ES256 — ECDSA + SHA-256
  • HS256 — HMAC + SHA-256
{
  "alg": "RS256"
}

В Jsrsasign это поле часто используется как подсказка при выборе алгоритма подписи или проверки JWT.


RSA ключи в формате JWK

RSA-ключи требуют дополнительных параметров:

  • n — модуль (modulus)
  • e — экспонента (public exponent)
  • d — приватная экспонента (только для приватных ключей)

Пример публичного RSA JWK:

{
  "kty": "RSA",
  "kid": "rsa-1",
  "use": "sig",
  "n": "base64url-modulus",
  "e": "AQAB"
}

Приватный RSA JWK:

{
  "kty": "RSA",
  "kid": "rsa-1",
  "d": "base64url-private-exponent",
  "n": "base64url-modulus",
  "e": "AQAB"
}

Особенности параметров RSA

  • n и e всегда присутствуют в публичной части
  • d присутствует только в приватной
  • значения кодируются в Base64URL без padding

EC ключи (Elliptic Curve JWK)

Для ключей на эллиптических кривых используются следующие поля:

  • crv — кривая (например, P-256)
  • x — координата X
  • y — координата Y
  • d — приватное значение (если ключ приватный)

Пример:

{
  "kty": "EC",
  "crv": "P-256",
  "kid": "ec-key-1",
  "x": "base64url-x",
  "y": "base64url-y"
}

Приватный вариант:

{
  "kty": "EC",
  "crv": "P-256",
  "x": "base64url-x",
  "y": "base64url-y",
  "d": "base64url-private"
}

Симметричные ключи (oct)

Тип oct используется для симметричных алгоритмов, например HMAC или AES.

Основное поле:

  • k — ключ в Base64URL

Пример:

{
  "kty": "oct",
  "k": "base64url-secret-key",
  "use": "sig",
  "alg": "HS256"
}

В отличие от RSA и EC, здесь нет разделения на публичную и приватную часть, так как ключ один и тот же для подписи и проверки.


Поле key_ops (операции с ключом)

key_ops определяет допустимые операции с ключом:

  • sign
  • verify
  • encrypt
  • decrypt
  • wrapKey
  • unwrapKey

Пример:

{
  "key_ops": ["sign", "verify"]
}

Это поле более строгое, чем use, так как явно перечисляет разрешённые действия.


Поле x5c (X.509 сертификаты)

x5c содержит цепочку сертификатов X.509 в формате Base64.

{
  "x5c": [
    "MIIC...base64cert..."
  ]
}

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


Поле x5t и x5t#S256

Эти поля представляют отпечаток сертификата:

  • x5t — SHA-1 thumbprint
  • x5t#S256 — SHA-256 thumbprint
{
  "x5t#S256": "base64url-thumbprint"
}

Они используются для быстрого сопоставления сертификатов без полного разбора цепочки.


JWKS: набор JWK ключей

JWK часто используется не по одному ключу, а в виде набора — JWKS (JSON Web Key Set).

Структура JWKS:

{
  "keys": [
    {
      "kty": "RSA",
      "kid": "key-1",
      "n": "...",
      "e": "AQAB"
    },
    {
      "kty": "EC",
      "kid": "key-2",
      "crv": "P-256",
      "x": "...",
      "y": "..."
    }
  ]
}

JWKS используется в системах авторизации (OAuth2, OpenID Connect) для динамической загрузки публичных ключей.


Особенности JWK в Jsrsasign

В библиотеке Jsrsasign JWK активно используется для:

  • создания ключей из JSON
  • преобразования PEM → JWK и обратно
  • работы с JWT (подпись и проверка)
  • обработки JWKS endpoint

Пример использования:

const rsaKey = KEYUTIL.getKey(jwkObject);

Jsrsasign автоматически интерпретирует поля JWK и преобразует их в внутренний формат ключа.


Кодировка значений

Все бинарные данные в JWK кодируются в Base64URL:

  • без символа =
  • с заменой +-
  • с заменой /_

Это критично для корректной работы с веб-протоколами.


Требования к корректному JWK

Корректный JWK должен:

  • содержать kty
  • соответствовать структуре выбранного типа ключа
  • использовать Base64URL для всех бинарных значений
  • иметь согласованные поля (use, alg, key_ops не должны противоречить друг другу)

Нарушение этих правил приводит к ошибкам при импорте ключа в Jsrsasign или при проверке JWT.


Взаимосвязь JWK и JWT

JWK напрямую используется для:

  • проверки подписи JWT (JWS)
  • шифрования JWT (JWE)
  • автоматической ротации ключей через JWKS endpoint

В типичном сценарии:

  1. сервер публикует JWKS
  2. клиент получает JWT
  3. извлекается kid
  4. выбирается соответствующий JWK
  5. выполняется проверка подписи

Эта схема позволяет безопасно обновлять ключи без остановки сервиса.