Understanding JSON Web Tokens (JWT), JWS, and JWE: Structure, Claims, and Encryption
This article provides a comprehensive overview of JSON Web Tokens, explaining their purpose, structure (header, payload, signature), key concepts such as JWS and JWE, the various claim types, encryption and signing algorithms, and practical usage considerations for secure web authentication.
What is JWT
A JWT is a compact, URL‑safe string consisting of three Base64URL‑encoded parts (header, payload, signature) that can be printed and used to verify the authenticity of a signed token.
Problems solved by JWT
JWTs enable secure transmission of claims between a client and a server, supporting authentication, authorization, federated identity, stateless sessions, and client secrets.
Key terminology
JWS – Signed JWT
JWE – Encrypted JWT (payload is encrypted)
JWK – JSON Web Key (the secret or key pair)
JWK Set – Collection of JWKs used for asymmetric encryption
JWA – JSON Web Algorithms
nonsecure JWT – JWT with "alg":"none" (no signature)
JWT composition
The three parts are separated by dots: xxxxx.yyyyy.zzzzz Example header (pretty‑printed JSON):
{
"typ": "JWT",
"alg": "none",
"jti": "4f1g23a12aa"
}The header declares the token type and the signing algorithm. Optional fields include jti (JWT ID) and cty (content type).
The payload contains registered, public, and private claims. Registered claims include: iss – issuer sub – subject aud – audience exp – expiration time nbf – not before iat – issued at jti – JWT ID
Public claims are defined by standards bodies; private claims are custom data shared between trusted parties.
JWS concept
JWS adds a digital signature to a JWT. The signature is created from the Base64URL‑encoded header and payload using a secret (HMAC) or a private key (RSA/ECDSA). Verification uses the corresponding secret or public key.
Supported signature algorithms:
HS256/HS384/HS512 (HMAC)
RS256/RS384/RS512 (RSA)
ES256/ES384/ES512 (ECDSA)
Signature creation example (HMAC‑SHA256):
RSASSA || ECDSA || HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)Resulting JWS token:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiIsImp0aSI6IjRmMWcyM2ExMmFhIn0.eyJpc3MiOiJodHRwOi8vc2hhb2Jhb2Jhb2VyLmNuIiwiYXVkIjoiaHR0cDovL3NoYW9iYW9iYW9lci5jbi93ZWJ0ZXN0L2p3dF9hdXRoLyIsImp0aSI6IjRmMWcyM2ExMmFhIiwiaWF0IjoxNTM0MDcwNTQ3LCJuYmYiOjE1MzQwNzA2MDcsImV4cCI6MTUzNDA3NDE0NywidWlkIjoxLCJkYXRhIjp7InVuYW1lIjoic2hhb2JhbyIsInVFbWFpbCI6InNoYW9iYW9iYW9lckAxMjYuY29tIiwidUlEIjoiMHhBMCIsInVHcm91cCI6Imd1ZXN0In19.GQPGEpixjPZSZ7CmqXB-KIGNzNl4Y86d3XOaRsfiXmQJWS extra header fields
Optional fields such as jku, jwk, kid, x5u, x5c, x5t, typ, and crit can be added for key discovery, certificate handling, or JOSE integration.
JWE concepts
JWE encrypts the JWT payload to protect its confidentiality. It consists of five Base64URL‑encoded parts:
Protected header
Encrypted key
Initialization vector (IV)
Ciphertext (encrypted data)
Authentication tag
Example compact JWE token:
eyJhbGciOiJSU0ExXzUiLCJlbmMiOiJBMTI4Q0JDLUhTMjU2In0.UGhIOguC7IuEvf_NPVaXsGMoLOmwvc1GyqlIKOK1nN94nHPoltGRhWhw7Zx0-kFm1NJn8LE9XShH59_i8J0PH5ZZyNfGy2xGdULU7sHNF6Gp2vPLgNZ__deLKxGHZ7PcHALUzoOegEI-8E66jX2E4zyJKxYxzZIItRzC5hlRirb6Y5Cl_p-ko3YvkkysZIFNPccxRU7qve1WYPxqbb2Yw8kZqa2rMWI5ng8OtvzlV7elprCbuPhcCdZ6XDP0_F8rkXds2vE4X-ncOIM8hAYHHi29NX0mcKiRaD0-D-ljQTPcFPgwCp6X-nZZd9OHBv-B3oWh2TbqmScqXMR4gp_A.AxY8DCtDaGlsbGljb3RoZQ.KDlTtXchhZTGufMYmOYGS4HffxPSUrfmqCHXaI9wOGY.9hH0vgRfYgPnAHOd8stkvwJWE key encryption algorithms
JWE supports five key‑management modes: Key Encryption, Key Wrapping, Direct Key Agreement, Key Agreement with Key Wrapping, and Direct Encryption. Not all JWA algorithms support every mode.
JWE header
Typical fields include type (usually "jwt"), alg (key‑encryption algorithm), enc (content‑encryption algorithm), optional zip (compression), and the same extra fields as JWS ( jku, kid, etc.).
JWE encryption process
Generate a random CEK (Content Encryption Key) based on alg.
Encrypt the CEK according to the selected key‑management mode.
Optionally generate an IV.
If zip is present, compress the plaintext.
Encrypt the (compressed) plaintext with the CEK, IV, and enc algorithm, producing ciphertext and an authentication tag.
Assemble the five parts:
base64(header) . base64(encryptedKey) . base64(iv) . base64(ciphertext) . base64(tag).
JWE serialization
In JSON General Serialization, the token is represented as an object with fields such as protected, unprotected, recipients (each containing header and encrypted_key), iv, ciphertext, and tag.
JWT workflow example (e.g., Juice Shop)
After a successful login, the server returns a JWT which the client stores (e.g., in localStorage, sessionStorage, or an http‑only cookie). Subsequent requests include the token in the Authorization: Bearer <token> header. The server validates the signature (or decrypts a JWE) and extracts claims to authorize the request.
Choosing a signing algorithm
HMAC (HS*) is fast and suitable for single‑service or one‑to‑one scenarios. RSA (RS*) or ECDSA (ES*) are preferred for one‑to‑many architectures because the private key signs once while many services can verify using the public key. For small micro‑service setups with a single key pair, HMAC may suffice; otherwise RSA is recommended.
Author: NinthDevilHunster (reprinted from FreeBuf.COM)
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
