ECDH-ES и ECDH-ES+AES-KW

ECDH-ES относится к классу алгоритмов согласования ключей в спецификации JWE (JSON Web Encryption) и используется библиотекой Jose для реализации гибридного шифрования на основе эллиптической криптографии. Основная идея заключается в том, что отправитель и получатель вычисляют общий секретный ключ через ECDH (Elliptic Curve Diffie-Hellman), после чего из этого секрета выводится ключ шифрования содержимого (CEK — Content Encryption Key).

ECDH-ES работает без передачи симметрического ключа по сети. Вместо этого используется эпhemeral-ключ отправителя и публичный ключ получателя, что делает схему устойчивой к перехвату трафика и обеспечивает прямую forward secrecy при корректной реализации.


В JWE алгоритм alg определяет способ защиты CEK. В случае ECDH-ES:

  • ключ шифрования содержимого не передаётся напрямую;
  • CEK вычисляется на стороне обеих участников;
  • используется Concat KDF (Key Derivation Function);
  • поддерживаются разные кривые: P-256, P-384, P-521, X25519, X448 (в зависимости от реализации Jose).

Структура JWE при ECDH-ES:

  • protected header содержит alg: "ECDH-ES" или расширенные варианты;
  • enc задаёт симметрический алгоритм шифрования контента (например, A256GCM);
  • epk (ephemeral public key) передаётся вместе с сообщением;
  • apu и apv — дополнительные параметры согласования ключа (optional context).

Механизм работы ECDH-ES

Процесс согласования ключа можно разложить на несколько этапов:

  1. Генерация ephemeral key pair отправителем Отправитель создаёт временную пару ключей на эллиптической кривой.

  2. Использование публичного ключа получателя Публичный ключ получателя используется вместе с ephemeral private key отправителя.

  3. Вычисление shared secret Оба участника независимо вычисляют общий секрет через ECDH.

  4. Derivation CEK через Concat KDF Из shared secret выводится CEK с использованием параметров:

    • алгоритма шифрования (enc)
    • идентификаторов сторон (apu, apv)
    • длины ключа
  5. Шифрование полезной нагрузки CEK используется с симметрическим алгоритмом (например AES-GCM).

Ключевая особенность ECDH-ES заключается в том, что CEK не инкапсулируется, а выводится напрямую.


Реализация ECDH-ES в Jose (Node.js)

Библиотека Jose предоставляет высокоуровневые API для работы с JWE.

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

import { generateKeyPair } from 'jose'

const { publicKey, privateKey } = await generateKeyPair('ECDH-ES', {
  crv: 'P-256'
})

Здесь создаётся ключевая пара на кривой P-256.


Шифрование с ECDH-ES

import { CompactEncrypt } from 'jose'

const encoder = new TextEncoder()

const jwe = await new CompactEncrypt(
  encoder.encode('Secret message')
)
  .setProtectedHeader({
    alg: 'ECDH-ES',
    enc: 'A256GCM'
  })
  .encrypt(publicKey)

В этом случае:

  • alg: ECDH-ES — способ согласования ключа;
  • enc: A256GCM — симметрическое шифрование данных.

Расшифрование

import { compactDecrypt } from 'jose'

const { plaintext } = await compactDecrypt(jwe, privateKey)

console.log(new TextDecoder().decode(plaintext))

При расшифровании происходит:

  • извлечение ephemeral public key;
  • повторное вычисление shared secret;
  • восстановление CEK;
  • расшифрование payload.

ECDH-ES и модель CEK

В чистом ECDH-ES CEK не передаётся и не шифруется отдельно. Он всегда производный:

  • shared secret → Concat KDF → CEK
  • CEK используется только для enc

Это делает схему более компактной, но накладывает ограничения:

  • нельзя напрямую управлять CEK;
  • невозможна интеграция с key wrapping стандартами без расширений.

ECDH-ES + AES-KW

Расширенный вариант алгоритма — ECDH-ES+A128KW, ECDH-ES+A192KW, ECDH-ES+A256KW.

В отличие от базового ECDH-ES:

  • сначала вычисляется shared secret через ECDH;
  • затем из него выводится KEK (Key Encryption Key);
  • CEK генерируется случайно;
  • CEK шифруется (wrap) через AES Key Wrap.

Отличие от чистого ECDH-ES

ECDH-ES

  • CEK выводится напрямую через KDF
  • нет отдельного wrapping слоя
  • меньше криптографических операций

ECDH-ES + AES-KW

  • CEK генерируется случайно
  • CEK шифруется отдельным ключом KEK
  • используется AES Key Wrap (RFC 3394)
  • более совместим с системами, где требуется отдельная защита ключа

Пример ECDH-ES+A256KW в Jose

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

import { generateKeyPair } from 'jose'

const { publicKey, privateKey } = await generateKeyPair('ECDH-ES+A256KW', {
  crv: 'P-256'
})

Шифрование

import { CompactEncrypt } from 'jose'

const jwe = await new CompactEncrypt(
  new TextEncoder().encode('Top secret data')
)
  .setProtectedHeader({
    alg: 'ECDH-ES+A256KW',
    enc: 'A256GCM'
  })
  .encrypt(publicKey)

Расшифрование

import { compactDecrypt } from 'jose'

const { plaintext } = await compactDecrypt(jwe, privateKey)

console.log(new TextDecoder().decode(plaintext))

Архитектурные различия внутри Jose

Внутри реализации Jose:

Для ECDH-ES

  • используется deriveKey через Concat KDF
  • напрямую создаётся CEK
  • минимальная криптографическая обвязка

Для ECDH-ES+A256KW

  • используется AES Key Wrap (RFC 3394)
  • отдельный этап генерации CEK
  • дополнительная криптографическая изоляция ключей

Concat KDF

Оба варианта используют KDF на основе:

  • Z (shared secret)
  • AlgorithmID
  • PartyUInfo / PartyVInfo
  • SuppPubInfo (длина ключа)

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


Безопасность и свойства схемы

ECDH-ES обеспечивает следующие свойства:

  • forward secrecy (при использовании ephemeral ключей)
  • отсутствие передачи секретного ключа
  • криптографическая изоляция сообщений
  • защита от replay при корректной реализации

ECDH-ES+AES-KW добавляет:

  • дополнительный слой защиты CEK
  • совместимость с legacy key wrapping системами
  • более строгую модель разделения ключей

Выбор алгоритма в практических системах

ECDH-ES предпочтителен, когда:

  • требуется минимальная задержка;
  • система полностью построена вокруг JWE;
  • нет требований к отдельному управлению CEK.

ECDH-ES+AES-KW используется, когда:

  • требуется интеграция с инфраструктурой key wrapping;
  • ключи должны быть разделены по ролям;
  • необходима строгая совместимость с криптосистемами, использующими AES-KW.

Типичные ошибки при использовании Jose

  • несоответствие кривых между сторонами (P-256 vs P-384)
  • неправильный выбор enc (например несовместимость с ключом)
  • попытка использовать один и тот же ephemeral key повторно
  • отсутствие проверки алгоритма в protected header

Структура JWE при ECDH-ES

Типичный компактный JWE:

header.
encrypted_key.
iv.
ciphertext.
tag

Для ECDH-ES поле encrypted_key часто пустое, так как CEK не шифруется напрямую.

Для ECDH-ES+A256KW:

  • encrypted_key содержит CEK, зашифрованный AES-KW.

Практическое применение

ECDH-ES в Jose используется в:

  • защищённых API коммуникациях;
  • мобильных приложениях с end-to-end encryption;
  • распределённых системах с публичными ключами пользователей;
  • OAuth/OIDC сценариях при защите payload.

ECDH-ES+AES-KW чаще встречается в:

  • корпоративных системах управления ключами;
  • гибридных криптосистемах;
  • интеграциях с HSM (Hardware Security Modules).