JWK для EC: crv, x, y, d

В формате JWK (JSON Web Key) EC-ключи описываются как набор параметров, отражающих математическую природу эллиптической криптографии. Для кривых типа EC (Elliptic Curve) ключ состоит из имени кривой, координат точки открытого ключа и, при наличии, приватного скалярного значения.

crv определяет используемую эллиптическую кривую. Это строковый идентификатор, который задаёт параметры математического пространства, в котором выполняются операции над ключами. На практике в Web Crypto и JWK чаще всего встречаются:

  • P-256 (secp256r1)
  • P-384
  • P-521

Каждая из этих кривых задаёт фиксированную группу параметров: модуль поля, коэффициенты уравнения кривой и порядок базовой точки. В контексте Jsrsasign значение crv критично для корректной интерпретации координат x и y.


Координаты открытого ключа: x и y

Параметры x и y представляют координаты точки на эллиптической кривой, которая является открытым ключом.

Эллиптическая кривая задаётся уравнением вида:

y^2 = x^3 + ax + b

Точка публичного ключа — это решение этого уравнения в конечном поле, заданном кривой crv.

Формат x и y в JWK

В JWK значения x и y не являются числами в привычном виде. Это:

  • байтовые строки фиксированной длины
  • закодированные в Base64URL без padding

Для кривой P-256 длина каждой координаты составляет 32 байта (256 бит), для P-384 — 48 байт, для P-521 — 66 байт (с особенностью округления до байтов).

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

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

Смысл координат

  • x — абсцисса точки на кривой
  • y — ордината точки на кривой

Они вместе образуют точку Q = (x, y), которая вычисляется из приватного ключа d через умножение базовой точки кривой:

Q = d G

где:

  • d — приватный ключ (скаляр)
  • G — базовая точка кривой
  • Q — публичный ключ

Приватный параметр d

Поле d присутствует только в приватном JWK. Оно представляет собой скалярное значение, которое используется для генерации публичного ключа.

Особенности d:

  • это случайное число в диапазоне [1, n-1], где n — порядок базовой точки
  • кодируется так же в Base64URL
  • должно быть строго секретным

В JWK структура приватного EC-ключа выглядит так:

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

Связь d и публичного ключа

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

Q = d G

Это означает, что зная d, можно вычислить x и y, но обратная операция вычислительно невозможна при корректных параметрах кривой.


Представление в Jsrsasign

Библиотека Jsrsasign предоставляет инструменты для работы с EC JWK через KEYUTIL и криптографические классы.

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

В Jsrsasign ключ можно создать и получить в формате JWK:

const kp = KEYUTIL.generateKeypair("EC", "P-256");
const pubJwk = KEYUTIL.getJWKFromKey(kp.pubKeyObj);
const privJwk = KEYUTIL.getJWKFromKey(kp.prvKeyObj);

В результате:

  • pubJwk содержит crv, x, y
  • privJwk дополнительно содержит d

Импорт EC JWK

Jsrsasign позволяет импортировать JWK обратно в объект ключа:

const keyObj = KEYUTIL.getKey(jwk);

При этом библиотека:

  • декодирует Base64URL значения
  • восстанавливает точку на кривой
  • проверяет соответствие x и y кривой crv

Если x и y не лежат на кривой, ключ считается некорректным.


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

Все значения x, y, d в JWK используют модифицированный Base64:

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

Это важно, поскольку JWK должен быть URL-safe и JSON-safe одновременно.


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

При работе с EC JWK важно учитывать несколько уровней корректности:

  1. Соответствие длины x, y кривой crv
  2. Принадлежность точки (x, y) эллиптической кривой
  3. Диапазон d (если присутствует)
  4. Соответствие публичного ключа вычисленному d · G

Jsrsasign выполняет часть этих проверок автоматически при создании KeyObject.


Использование EC JWK в криптографических операциях

EC JWK в Jsrsasign применяется в:

  • цифровой подписи (ECDSA)
  • проверке подписи
  • TLS-подобных сценариях
  • JWT (ES256, ES384, ES512)

Пример подписи:

const sig = new KJUR.crypto.Signature({ "alg": "SHA256withECDSA" });
sig.init(privKeyObj);
sig.updateString("data");
const signature = sig.sign();

Публичный ключ с x и y используется для проверки:

const ver = new KJUR.crypto.Signature({ "alg": "SHA256withECDSA" });
ver.init(pubKeyObj);
ver.updateString("data");
const isValid = ver.verify(signature);

Особенности работы с кривыми

Каждая кривая задаёт разные параметры безопасности и размер ключей:

  • P-256 — баланс производительности и стойкости
  • P-384 — повышенная криптостойкость
  • P-521 — максимальная длина ключа среди стандартных NIST-кривых

Изменение crv напрямую влияет на:

  • длину x, y, d
  • скорость операций
  • устойчивость к атакам перебора

Типичные ошибки при работе с EC JWK

Часто встречаются следующие проблемы:

  • несоответствие длины x и y выбранной кривой
  • повреждённый Base64URL (потеря символов или padding)
  • использование неправильного crv
  • попытка использовать d как публичный параметр
  • несоответствие точки кривой математическим условиям

Структурная роль полей

EC JWK можно рассматривать как строгую связку трёх уровней:

  • crv — определение математической системы
  • x, y — публичное представление точки
  • d — приватный генератор этой точки

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