JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with the HMAC algorithm) or a public/private key pair using RSA or ECDSA.
Although JWTs can be encrypted to also provide secrecy between parties, we will focus on signed tokens. Signed tokens can verify the integrity of the claims contained within it, while encrypted tokens hide those claims from other parties. When tokens are signed using public/private key pairs, the signature also certifies that only the party holding the private key is the one that signed it.
In its compact form, JSON Web Tokens consist of three parts separated by dots (.), which are:
- Header
- Payload
- Signature
Whenever the user wants to access a protected route or resource, the user agent should send the JWT, typically in the Authorization header using the Bearer schema.
Validation and Verification
Validate a JWT to make sure the token makes sense, adheres to the expected standards, contains the right data.
Verify a JWT to make sure the token hasn't been altered maliciously and comes from a trusted source.
JWT validation generally refers to checking the structure, format, and content of the JWT:
- Structure: Ensuring the token has the standard three parts (header, payload, signature) separated by dots.
- Format: Verifying that each part is correctly encoded (Base64URL) and that the payload contains expected claims.
- Content: Checking if the claims within the payload are correct, such as expiration time (exp), issued at (iat), not before (nbf), among others, to ensure the token isn't expired, isn't used before its time, etc.
JWT verification involves confirming the authenticity and integrity of the token:
- Signature Verification: This is the primary aspect of verification where the signature part of the JWT is checked against the header and payload. This is done using the algorithm specified in the header (like HMAC, RSA, or ECDSA) with a secret key or public key. If the signature doesn't match what's expected, the token might have been tampered with or is not from a trusted source.
- Issuer Verification: Checking if the iss claim matches an expected issuer.
- Audience Check: Ensuring the aud claim matches the expected audience.
source: https://www.jwt.io/introduction#when-to-use-json-web-tokens
Public and Private Keys with JWTs
With JWT, the possession and the use of the key materials are exactly the same as in any other contexts where cipher operations occur.
Signing
- The private key is owned by the issuer and is used to compute the signature.
- The public key can be shared with all parties that need to verify the signature.
Encryption
- The private key is owned by the recipient and is used to decrypt the data.
- The public key can be shared with any party that wants to send sensitive data to the recipient.
Encryption is rarely used with JWT. Most of the time the HTTPS layer is sufficient and the token itself only contains a information that is not sensitive.
The issuer of the token (the authentication server) has a private key to generate signed tokens (JWS). These tokens are sent to the clients (an API server, a web/native application).
The clients can verify the token with the public key. The key is usually fetched using a public URI.
If you have sensitive data that shall not be disclosed to a third party (phone numbers, personal address), then the encrypted tokens (JWE) are highly recommended. In this case, each client (i.e. recipient of a token) shall have a private key and the issuer of the token must encrypt the token using the public key of each recipient. This means that the issuer of the token can select the appropriate key for a given client.