Signed JWTs (JWS) ensure integrity and authenticity but are readable by anyone, while encrypted JWTs (JWE) ensure confidentiality, making the payload unreadable without the decryption key.
A signed JWT (JSON Web Signature, JWS) uses a secret or private key to create a digital signature over the header and payload. This guarantees that the token has not been tampered with and that it came from the expected issuer. However, the payload is only Base64Url-encoded, not encrypted, so anyone can decode and read its contents. Signing is used when you need to verify authenticity and integrity but do not require confidentiality.
An encrypted JWT (JSON Web Encryption, JWE) encrypts the payload using a symmetric or asymmetric encryption algorithm. The result is a ciphertext that can only be decrypted by the intended recipient who possesses the appropriate decryption key. This ensures confidentiality, meaning even if an attacker intercepts the token, they cannot read the sensitive data inside. Encryption is used when the token carries sensitive information that must be hidden from unauthorized parties.
Purpose: Signing provides integrity and authenticity; encryption provides confidentiality.
Readability: Signed JWTs are Base64Url-encoded and can be decoded by anyone; encrypted JWTs are unreadable without the decryption key.
Algorithms: Signing uses algorithms like HS256, RS256, ES256; encryption uses algorithms like RSA-OAEP, A128GCM, A256KW.
Use cases: Signing is used for access tokens, ID tokens where the payload is not sensitive; encryption is used when the token contains sensitive data like personal information or payment details.
Combined: It is possible to sign an encrypted JWT or encrypt a signed JWT to get both properties (JWS nested in JWE or vice versa).