JWT Decoder
Paste a JSON Web Token to read its header and payload as formatted JSON, with exp, nbf and iat shown as UTC times and as “in 2 hours” or “3 days ago”. The example token has the header {"alg":"HS256","typ":"JWT"} and the payload {"sub":"1234567890","name":"John Doe","iat":1516239022}; its iat of 1516239022 is 2018-01-18 01:30:22 UTC, and its signature is 32 bytes. The tool flags expired and not-yet-valid tokens, “alg”: “none”, a wrong number of parts, invalid base64url and parts that are not JSON. To check an HS256, HS384 or HS512 signature, type the secret and the tool computes the HMAC in your browser. Everything runs on your device: the token and the secret are never uploaded, stored or sent to analytics.
Updated Runs in your browser: nothing you enter is uploadedHow this tool works
The token is decoded on this device. It is never uploaded, saved or counted: the site only records that the tool was used, not what you pasted.
Decoded a signed token (HS256). Its signature is not checked unless you add a secret below.
Header
Payload
Times
exp, nbf and iat are seconds since 1970-01-01 UTC. Relative times use this device’s clock.
Signature
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
32 bytes (256 bits), not decoded here: it is the raw output of the signature algorithm.
Check the signature (optional)
For HS256, HS384 and HS512 tokens. Type the shared secret; the HMAC is computed in your browser and the secret is never sent or saved.
The example token, part by part
| Part | As written (base64url) | Decoded |
|---|---|---|
| Header | eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 | {"alg":"HS256","typ":"JWT"} |
| Payload | eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ | {"sub":"1234567890","name":"John Doe","iat":1516239022} |
| Signature | SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c | 32 bytes of HMAC output (not text) |
Registered claims
| Claim | Name | Meaning | In the example |
|---|---|---|---|
| iss | Issuer | Who created and signed the token. | not in the example |
| sub | Subject | Who the token is about, usually a user ID. | "1234567890" |
| aud | Audience | Who the token is meant for; a service should reject tokens not addressed to it. | not in the example |
| exp | Expiration time | From this moment the token must not be accepted. Seconds since 1970-01-01 UTC. | not in the example |
| nbf | Not before | Before this moment the token must not be accepted. Seconds since 1970-01-01 UTC. | not in the example |
| iat | Issued at | When the token was created. Seconds since 1970-01-01 UTC. | 1516239022 = 2018-01-18 01:30:22 UTC |
| jti | JWT ID | A unique identifier for this token, useful to detect replays. | not in the example |
Signing algorithms you will see in “alg”
| alg | Kind | Hash | Checked here |
|---|---|---|---|
| HS256 | HMAC with a shared secret | SHA-256 | Yes, with the secret |
| HS384 | HMAC with a shared secret | SHA-384 | Yes, with the secret |
| HS512 | HMAC with a shared secret | SHA-512 | Yes, with the secret |
| RS256 | RSA signature (public key) | SHA-256 | Decoded only (needs the public key) |
| ES256 | ECDSA signature (public key) | SHA-256 | Decoded only (needs the public key) |
| EdDSA | Edwards-curve signature (public key) | built in | Decoded only (needs the public key) |
| none | No signature at all | none | Nothing to check |
How to decode a JWT
- Paste the token. Replace the example with your token. A leading “Bearer ” or “Authorization:” prefix, quotes and line breaks are ignored.
- Read the header and payload. They appear as formatted JSON as you type. The header says how the token was signed; the payload holds the claims.
- Check the times and flags. exp, nbf and iat are shown in UTC and relative to now. Expired, not yet valid, “alg”: “none” and malformed parts are flagged.
- Optionally verify the signature. For HS256, HS384 or HS512 tokens, type the shared secret in the verify box to see whether the signature matches.
Frequently asked questions
- Is it safe to paste my JWT here?
- The token is decoded by JavaScript in your browser and is not uploaded, stored or included in analytics; the site only records that the tool was used. Still, a live token is a credential until it expires: avoid pasting production tokens into any site you do not trust, and treat a token you have shared as exposed.
- Is a JWT encrypted?
- A normal signed JWT (a JWS) is not encrypted: the header and payload are only base64url-encoded, so anyone holding the token can read them, which is exactly what this tool does. Never put secrets in the payload. Encrypted tokens (JWE) have five parts and need a key to read.
- Does decoding prove the token is valid?
- No. Decoding only reads the claims. Whether the token is genuine depends on checking the signature with the right key, and whether it is acceptable depends on exp, nbf, the issuer and the audience. A decoded token can be forged or expired.
- What does alg none mean?
- The token declares that it has no signature. RFC 7519 allows such “unsecured” tokens, but anyone can write one, so servers must never accept them as proof of identity. Some old libraries once let attackers switch a token to “none” to bypass checks; a verifier should decide the allowed algorithms itself and not trust the token’s header.
- How are exp, iat and nbf measured?
- As NumericDate values: seconds since 1970-01-01 00:00:00 UTC, not milliseconds. A value like 1516239022 is 2018-01-18 01:30:22 UTC. A 13-digit number is probably milliseconds, a common mistake that puts the date thousands of years ahead. The tool warns about it.
- Why does it say my token is expired when my server accepts it?
- This tool compares exp with your device’s clock and allows no tolerance. Servers often accept a small clock skew, commonly 30 to 60 seconds. If the time shown differs a lot, check your device’s clock.
- What does “invalid base64url” mean?
- JWT parts use the URL-safe Base64 alphabet (A–Z, a–z, 0–9, “-” and “_”) with no “=” padding. A “+”, “/”, “=”, space or any other character, or a length that cannot encode whole bytes, makes the part invalid. The tool names the first bad character and its position in that part.
- How does signature verification work here?
- For HS256, HS384 and HS512 the signature is an HMAC of the text “header.payload” under a shared secret, using SHA-256, SHA-384 or SHA-512. The tool recomputes it with the browser’s Web Crypto API and compares. The example verifies with the public sample secret “your-256-bit-secret”. RS256, ES256 and the other public-key algorithms are decoded but not verified.
- Which claims are standard?
- RFC 7519 registers iss, sub, aud, exp, nbf, iat and jti. Any other name, such as “name” or “role”, is a private claim defined by whoever issues the token. The table above lists the registered ones.
How it works
The token is trimmed of an optional “Bearer ” or “Authorization:” prefix, quotes and whitespace, then split at the dots. A compact JWS (RFC 7515) has exactly three parts; five parts mean an encrypted JWE, which cannot be read. Header and payload are decoded from base64url (RFC 4648 §5: the alphabet with “-” and “_”, no padding), read as strict UTF-8, parsed as JSON and printed with two-space indentation. The signature is shown as written, with its byte length. exp, nbf and iat must be numbers; each is shown as a UTC date from a JavaScript Date and, in the browser only, relative to the device clock, using whole units rounded down (a month is 30 days, a year 365). A token is flagged expired when exp is at or before now and not yet valid when nbf is after now, with no leeway. The page itself is static and never embeds the build time. Signature checks recompute the HMAC (RFC 2104) of the ASCII text “header.payload” with SubtleCrypto, using the secret as UTF-8 text, and compare it with the signature in constant time. Nothing is sent over the network.
Sources
More free tools
- Base64 Encode & DecodeEncode text or a file to Base64 and decode it back, with correct UTF-8 for emoji and any language, URL-safe and MIME variants. Runs in your browser.
- JSON Formatter & ValidatorValidate JSON with the exact line and column of any error, then pretty-print, minify or sort keys. Big numbers keep every digit. Runs in your browser.
- Unix Timestamp ConverterConvert a Unix timestamp to a date and a date to a timestamp. Seconds to nanoseconds, any time zone, plus a live counter of the current Unix time.
- Hash GeneratorHash text or a file with SHA-256, SHA-1, SHA-384, SHA-512, MD5 and CRC32, add an HMAC key, and check a checksum. Runs in your browser; nothing is uploaded.
- Password GeneratorMake a strong random password or passphrase on your device: choose length and characters, see its strength in bits and copy it. Nothing is sent.
- Password Strength CheckerCheck how strong your password is: a 0–4 score, crack times, and the patterns that weaken it, with tips to fix them. Checked on your device, never sent.