Security Glossary

JSON Web Encryption (JWE)

A standard (RFC 7516) for encrypting JWT content into a five-part compact token, adding confidentiality on top of JWS integrity, but only safe when weak key-wrapping like RSA1_5 is rejected and...

JSON Web Encryption (JWE) is a standard (RFC 7516) for encrypting a payload and representing the result as a compact JSON structure. JWS gives integrity and authentication over a cleartext payload, JWE gives confidentiality by encrypting it. The two solve different problems, and using JWE does not remove your obligation to validate the token's claims and algorithm.

Compact Structure

A JWE in compact serialization has five Base64URL parts joined by dots:

header.encrypted_key.iv.ciphertext.tag

eyJhbGciOiJSU0EtT0FFUCIsImVuYyI6IkEyNTZHQ00ifQ.   <- protected header {alg,enc}
OKOawDo13gRp2ojaHV7LFpZcgV7T6DVZKTyKOMTYUmKoTCVJRgckCL9kiMT03JGe.  <- CEK wrapped
48V1_ALb6US04U3b.                                  <- IV
5eym8TW_c8SuK0ltJ3rpYI.                            <- ciphertext
XFBoMYUZodetZdvTiFvSkQ                             <- authentication tag
  • Protected header: key management algorithm (alg) and content encryption algorithm (enc).
  • Encrypted key: a fresh random Content Encryption Key (CEK) wrapped for the recipient using alg.
  • IV / ciphertext / tag: the payload encrypted under the CEK with an AEAD scheme named by enc (for example A256GCM), with the header authenticated as AAD.

The RSA1_5 Padding Oracle

The alg value RSA1_5 wraps the CEK with RSAES-PKCS1-v1_5. That padding is vulnerable to Bleichenbacher's adaptive chosen-ciphertext attack: an attacker who can distinguish "padding valid" from "padding invalid" recovers the CEK one query at a time (the classic "Million Message Attack"). In JWE the oracle is often the decryption endpoint's own behavior. A different error, status code, or response time for a malformed wrapped key leaks the padding-validity bit.

// Attacker replaces the encrypted_key with crafted values
// and watches how the server responds:
// distinct 400 vs 500, or a timing gap, is the oracle
POST /token/decrypt
{ alg: RSA1_5 }  ...tampered encrypted_key...
=> recover CEK, then decrypt ciphertext offline

Prefer RSA-OAEP (or RSA-OAEP-256), whose OAEP padding is designed to resist this, or asymmetric schemes like ECDH-ES and symmetric wrapping (A256KW, dir) where no RSA PKCS#1 v1.5 step exists. Libraries that still accept RSA1_5 should be configured to reject it, and decryption code should behave identically regardless of where unwrapping fails.

Invalid-Curve Attacks on ECDH-ES

ECDH-ES derives the CEK from an ECDH exchange using the sender's ephemeral public key from the header (epk). If the recipient does not check that epk lies on the expected curve and is not a low-order point, an attacker submits points on a weaker curve and recovers the private key through repeated exchanges (an invalid-curve attack). Any JWE library or handler using ECDH-ES must validate the incoming epk before performing the multiplication.

Algorithm Confusion and Header Trust

  • Pin the algorithm. Decide alg and enc from your policy, not from the attacker-controlled header. Accepting whatever alg the token declares reintroduces RSA1_5 and enables downgrade.
  • Confidentiality is not authentication of claims. After decrypting you still validate iss, aud, exp, and the like. For signed-and-encrypted tokens, nest a JWS inside the JWE (sign then encrypt) and verify the inner signature.
  • Reject compression surprises. A zip: DEF header inflates attacker data before decryption; cap decompressed size to avoid a decompression bomb.

PentesterLab Exercises

See Also