Skip to main content
ponderloop

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

Stays in your browser

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.

Issued at (iat)
2018-01-18 01:30:22 UTC
Raw value: 1516239022

Signature

SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

32 bytes (256 bits), not decoded here: it is the raw output of the signature algorithm.

The example token, part by part

A JWT is three base64url strings joined by dots. The first two decode to JSON; the third is binary.
PartAs written (base64url)Decoded
HeadereyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9{"alg":"HS256","typ":"JWT"}
PayloadeyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ{"sub":"1234567890","name":"John Doe","iat":1516239022}
SignatureSflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c32 bytes of HMAC output (not text)

Registered claims

The seven claim names RFC 7519 defines. All are optional; the three times are NumericDate values: whole or fractional seconds since 1970-01-01 UTC, not milliseconds.
ClaimNameMeaningIn the example
issIssuerWho created and signed the token.not in the example
subSubjectWho the token is about, usually a user ID."1234567890"
audAudienceWho the token is meant for; a service should reject tokens not addressed to it.not in the example
expExpiration timeFrom this moment the token must not be accepted. Seconds since 1970-01-01 UTC.not in the example
nbfNot beforeBefore this moment the token must not be accepted. Seconds since 1970-01-01 UTC.not in the example
iatIssued atWhen the token was created. Seconds since 1970-01-01 UTC.1516239022 = 2018-01-18 01:30:22 UTC
jtiJWT IDA unique identifier for this token, useful to detect replays.not in the example

Signing algorithms you will see in “alg”

The header’s “alg” says how the signature was made. This tool checks only the HMAC ones, because they need nothing but the secret.
algKindHashChecked here
HS256HMAC with a shared secretSHA-256Yes, with the secret
HS384HMAC with a shared secretSHA-384Yes, with the secret
HS512HMAC with a shared secretSHA-512Yes, with the secret
RS256RSA signature (public key)SHA-256Decoded only (needs the public key)
ES256ECDSA signature (public key)SHA-256Decoded only (needs the public key)
EdDSAEdwards-curve signature (public key)built inDecoded only (needs the public key)
noneNo signature at allnoneNothing to check

How to decode a JWT

  1. Paste the token. Replace the example with your token. A leading “Bearer ” or “Authorization:” prefix, quotes and line breaks are ignored.
  2. 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.
  3. 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.
  4. 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

All toolsHome & DIY calculators