Skip to content

ECDH-ES decrypt support in /v1/crypto/decrypt #1033

Description

@HatemMn

Priority: Low — future improvement, not blocking any current release.


Background

The KMS already publishes EC public keys (P-256, P-384) via the JWKS endpoint
(GET /.well-known/jwks.json). Any JOSE-compliant client seeing those keys in
JWKS will naturally try to encrypt payloads using ECDH-ES or ECDH-ES+A128KW
(RFC 7518 §4.6) — the default key-management algorithm for EC keys in the web ecosystem.

Currently, the /v1/crypto/decrypt endpoint only handles dir and RSA-OAEP /
RSA-OAEP-256. This creates a gap: the JWKS endpoint advertises EC keys that the
decrypt endpoint cannot use for JWE decryption.


What ECDH-ES is

Ephemeral-static Diffie-Hellman key agreement. The sender:

  1. Generates a throwaway EC key pair (the epk field in the JWE header).
  2. Performs DH against the recipient's static EC public key.
  3. Derives a CEK from the shared secret using Concat KDF (RFC 7518 Appendix C).

The KMS would only need the static private key — which never leaves the server.

Variants to support:

  • ECDH-ES — derived key is the CEK directly (no wrapping, enc must match key size)
  • ECDH-ES+A128KW — derived key wraps a random CEK with AES-128 Key Wrap
  • ECDH-ES+A256KW — same, with AES-256 Key Wrap

Proposed implementation scope

  • Feature flag: non-fips (start there; ECDH is SP 800-56A approved so FIPS
    promotion is feasible in a follow-up once validated against the FIPS provider).
  • Server-side pipeline (no key material leaves the server):
    1. Parse JWE protected header → extract alg, enc, epk, apu, apv, kid
    2. KMIP Get(kid) → static EC private key
    3. EVP_PKEY_derive(static_privkey, epk)shared_z
    4. Concat KDF(shared_z, alg, apu, apv) → CEK or KEK
    5. For +A128KW/+A256KW: AES-KW unwrap encrypted_key → CEK
    6. AES-GCM decrypt → plaintext
  • New JoseAlgorithm variants: EcdhEs, EcdhEsA128KW, EcdhEsA256KW
  • Supported curves: P-256, P-384 (P-521 optional)
  • Test vectors: RFC 7518 Appendix B + own KMS vectors

Why this matters

Without ECDH-ES decrypt, the JWKS-published EC keys are only usable for signature
verification
. Clients that want to encrypt data to the KMS using its EC public key
have no supported path. RSA-OAEP remains the only encryption option, which forces
users to generate RSA keys instead of the more modern and compact EC keys.


Out of scope for this issue

  • JWT issuance or OIDC
  • ECDH-ES encrypt (the KMS is a decryption oracle; senders use the public key directly)
  • X25519 / X448 (OKP key type) — separate issue if desired

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Fields

    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions