Context
The v2 rewrite (#26) covers the JWS half of JOSE (RFC 7515 / 7517 / 7518 §3 / 7519 / 7638) but does not implement JWE (JSON Web Encryption, RFC 7516 + RFC 7518 §4–§5).
JWE was deferred from v2 because the surface is large and several modes are security-sensitive — particularly the AES-CBC-HMAC content-encryption family, which requires a constant-time MAC-then-decrypt check to avoid padding-oracle bugs.
Request
Add Protect-Jwt and Unprotect-Jwt covering the JWE compact serialization with the algorithm matrix below.
Technical Decisions
Surface
Protect-Jwt — accepts a [Jwt] (or claims hashtable), a content-encryption algorithm (enc), a key-management algorithm (alg), and the recipient key. Returns a JWE compact string.
Unprotect-Jwt — accepts a JWE compact string and the recipient key. Returns a [Jwt] (or the decrypted plaintext if the payload is not a JWT).
Algorithm matrix (RFC 7518 §4 + §5)
Key management (alg):
| Algorithm |
Status |
Notes |
RSA-OAEP-256 |
Implement |
Modern profile, mandatory in OpenID Connect |
RSA-OAEP |
Implement |
SHA-1 OAEP, kept for interop |
RSA1_5 |
Refuse |
Bleichenbacher-vulnerable; throw with a pointer to RSA-OAEP-256 |
dir |
Implement |
Direct symmetric key |
A128KW / A192KW / A256KW |
Implement |
AES Key Wrap (RFC 3394) |
A128GCMKW / A192GCMKW / A256GCMKW |
Implement |
AES-GCM Key Wrap |
ECDH-ES |
Implement |
ECDH-ES with P-256 / P-384 / P-521 |
ECDH-ES+A128KW / +A192KW / +A256KW |
Implement |
ECDH-ES with key wrap |
PBES2-HS256+A128KW / +HS384+A192KW / +HS512+A256KW |
Implement |
Password-based |
Content encryption (enc):
| Algorithm |
Status |
Notes |
A128GCM / A192GCM / A256GCM |
Implement |
AES-GCM via System.Security.Cryptography.AesGcm |
A128CBC-HS256 / A192CBC-HS384 / A256CBC-HS512 |
Implement |
AES-CBC + HMAC; MAC-then-decrypt with constant-time compare |
Security notes
- AES-CBC-HMAC: compute and verify the HMAC over the AAD || IV || ciphertext || AAD-length before decrypting. Use
CryptographicOperations.FixedTimeEquals for the MAC compare.
- ECDH-ES: derive the CEK with the Concat KDF (RFC 7518 §4.6.2) — do not reuse
HKDF.
- PBES2: enforce a minimum iteration count (start at 600 000, matching OWASP 2023 guidance) and reject lower values from incoming tokens with a clear error.
RSA1_5 is intentionally absent. The error message must point users at RSA-OAEP-256.
Out of scope
- JWE general (non-compact) serialization with multiple recipients — can be a follow-up to this issue.
- EdDSA / OKP — tracked separately.
Context
The v2 rewrite (#26) covers the JWS half of JOSE (RFC 7515 / 7517 / 7518 §3 / 7519 / 7638) but does not implement JWE (JSON Web Encryption, RFC 7516 + RFC 7518 §4–§5).
JWE was deferred from v2 because the surface is large and several modes are security-sensitive — particularly the AES-CBC-HMAC content-encryption family, which requires a constant-time MAC-then-decrypt check to avoid padding-oracle bugs.
Request
Add
Protect-JwtandUnprotect-Jwtcovering the JWE compact serialization with the algorithm matrix below.Technical Decisions
Surface
Protect-Jwt— accepts a[Jwt](or claims hashtable), a content-encryption algorithm (enc), a key-management algorithm (alg), and the recipient key. Returns a JWE compact string.Unprotect-Jwt— accepts a JWE compact string and the recipient key. Returns a[Jwt](or the decrypted plaintext if the payload is not a JWT).Algorithm matrix (RFC 7518 §4 + §5)
Key management (
alg):RSA-OAEP-256RSA-OAEPRSA1_5RSA-OAEP-256dirA128KW/A192KW/A256KWA128GCMKW/A192GCMKW/A256GCMKWECDH-ESECDH-ES+A128KW/+A192KW/+A256KWPBES2-HS256+A128KW/+HS384+A192KW/+HS512+A256KWContent encryption (
enc):A128GCM/A192GCM/A256GCMSystem.Security.Cryptography.AesGcmA128CBC-HS256/A192CBC-HS384/A256CBC-HS512Security notes
CryptographicOperations.FixedTimeEqualsfor the MAC compare.HKDF.RSA1_5is intentionally absent. The error message must point users atRSA-OAEP-256.Out of scope