JWE Decoder
Decrypt JSON Web Encryption (JWE) tokens with your own key, or inspect and validate them without one. Everything runs in your browser. · Updated
A JWE has five parts: a protected header, an encrypted key, an initialization vector, the ciphertext, and an authentication tag. The header's alg says how the content key reaches the recipient (sent wrapped, agreed by ECDH, derived from a password, or shared in advance with dir), and enc says how the payload itself was encrypted. This decoder reads both, checks that every part has the size those algorithms require, and, given the recipient's key, recovers the content key and decrypts the payload with the browser's Web Crypto API. The header is authenticated along with the ciphertext, so a token whose header was edited fails to decrypt even though its ciphertext is untouched. Nested tokens are common: when cty is JWT the decrypted payload is a signed JWT, whose claims are shown here and whose signature you can then verify in the JWT Decoder.
Common errors and fixes
Decryption failed: the key does not match this token, or the token was altered after it was issued.
Check the token's kid against your key set and confirm the key comes from the same environment as the token. Re-copy the token in full: one changed character fails authentication.
This JWK is a public key: it has no d member.
Decryption needs the recipient's private key. Export the private JWK (it includes d) from your key store; the public key can only encrypt.
This is a SEC1 "EC PRIVATE KEY", which browsers cannot import.
Convert the key to PKCS #8 with: openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem, then paste the BEGIN PRIVATE KEY block.
Invalid JWE compact serialization: found 3 dot-separated parts, expected 5 (header.encrypted_key.iv.ciphertext.tag).
Three parts is a signed JWT, not a JWE. Open it in the JWT Decoder. A JWE always has five parts, and the encrypted key may be empty, leaving two dots in a row.
A256GCM requires a 12-byte IV, but this one is 16 bytes.
The issuer generated the wrong IV size for AES-GCM. Generate 96 random bits (12 bytes) per token; 16-byte IVs belong to the AES-CBC-HMAC enc values.
Options
| Option | Description |
|---|---|
| Key | Optional. The key that decrypts the token: a private JWK, a PEM private key, a hex or Base64 secret, or the password of a PBES2 token. Leave it empty to inspect without decrypting. It is never saved, put in a URL, or sent anywhere. |
| Key format | How to read the key. Auto-detect recognises JWK and PEM, and for a symmetric secret picks whichever of hex, Base64 or plain text gives the key size the token needs. Set it yourself when a secret is ambiguous, such as a 32-character string that is also valid hex. |
FAQ
Does this tool decrypt JWE payloads?
Yes, when you give it the key. Paste the token, put the key in the Key option, and the payload is decrypted in your browser with the Web Crypto API and shown as JSON claims, a nested JWT, or text. Without a key it still decodes the header, validates every part, and tells you which key you need.
Is it safe to paste a private key here?
The key stays in this tab's memory: it is never written to storage, never put in a URL, and never sent anywhere. When you press Format the page makes two requests, which you can see in your browser's network panel: it downloads the decoder's code, and it sends a usage ping containing only the tool's name. Neither carries the token or the key. Drafts, history and share links are switched off for this tool. That said, a production private key is safest never leaving its key store, so prefer a development or test key when you can.
Which key formats are accepted?
A JWK (private RSA, EC or OKP key, or kty oct for a symmetric key), a PEM private key in PKCS #8 (BEGIN PRIVATE KEY) or PKCS #1 (BEGIN RSA PRIVATE KEY) form, a symmetric secret as hex or Base64, and a plain password for PBES2 tokens. A SEC1 BEGIN EC PRIVATE KEY block must be converted to PKCS #8 first; the error message gives the openssl command.
Which JWE algorithms are supported?
Key management: dir, A128KW, A192KW, A256KW, the AES-GCM key wrap variants, RSA-OAEP with SHA-1, SHA-256, SHA-384 or SHA-512, ECDH-ES on P-256, P-384, P-521 and X25519 with or without key wrap, and PBES2. Content encryption: A128GCM, A192GCM, A256GCM, A128CBC-HS256, A192CBC-HS384 and A256CBC-HS512, with DEFLATE (zip: DEF) payloads inflated. RSA1_5 is validated but not decrypted, because browsers do not implement it and it is deprecated. Chromium browsers cannot use 192-bit AES keys.
What key do I need to decrypt my JWE?
It depends on alg, and the report names it: dir uses the shared symmetric key directly, RSA-OAEP needs the recipient's RSA private key, ECDH-ES needs the recipient's EC private key for the curve in epk, and PBES2 needs the password. The kid header, when present, tells you which key in your key set the issuer used.
Why does decryption fail with the right key?
The usual causes are a key from another environment or an older kid, a symmetric secret read in the wrong encoding (hex read as text gives a different key), a dir key whose size does not match enc, or a token that lost characters when it was copied. The header is authenticated too, so re-encoding or editing it breaks decryption even when the ciphertext is intact.
How is JWE different from JWT?
JWT (JWS) uses three segments and is signed. JWE compact form uses five segments and encrypts the payload.
What if I paste a normal JWT?
A three-part token is reported as a signed JWT with a pointer to the JWT Decoder. A five-part token whose header has a signature alg and no enc is flagged as a JWS header.