Paste a JSON Web Token to inspect its header, payload, and signature — 100% in your browser with Web Crypto, zero server uploads.
What each token segment holds, how HS256, RS256 and ES256 differ, and which checks RFC 8725 requires.
A JWT in compact serialization (JWS, RFC 7515) is three unpadded Base64URL strings joined by dots: header.payload.signature. The header declares "alg" and optionally "kid", which selects a key inside a JWKS document. The payload carries the registered claims from RFC 7519 section 4.1: "iss", "sub", "aud", "exp", "nbf", "iat" and "jti". The three time claims use the NumericDate type, meaning Unix seconds rather than milliseconds: passing Date.now() without dividing by 1000 mints tokens that expire in the year 57000 and that no validator will reject. The signature covers the exact ASCII string "base64url(header).base64url(payload)", so re-serializing the JSON with different key order or indentation already invalidates the token.
HS256 computes an HMAC-SHA-256 over a shared secret, which means any party able to verify is also able to mint tokens. That is acceptable inside a monolith that signs and validates its own sessions, provided the secret is at least 256 random bits: RFC 7518 requires an HMAC key no smaller than the hash output. RS256 signs with RSASSA-PKCS1-v1_5 and a private key of 2048 bits or more, so consumers only need the public half, usually published at /.well-known/jwks.json. ES256 (ECDSA over P-256) offers equivalent strength with 64-byte signatures instead of the 256 bytes of RSA-2048, which matters when the token rides in every Authorization header.
RFC 8725 collects the failures that keep reappearing in production. With "alg": "none" an attacker submits an unsigned token and a naive validator accepts it because it trusts a header the attacker controls; the fix is a server-side allowlist of algorithms. Algorithm confusion swaps RS256 for HS256 and signs using the RSA public key as the HMAC secret, which older libraries permitted because verification took a single "key" argument. Injection through "jku", "x5u" or "kid" redirects key resolution to an attacker-controlled host or path: constrain "kid" to a known set and never fetch URLs supplied in the header. Validating "iss" and "aud" additionally stops a legitimate token issued for another service from being replayed.
Not natively: a JWS is self-contained and the validator consults no state. The common patterns are a short "exp" of 5 to 15 minutes paired with an opaque refresh token stored in a database, a denylist keyed by "jti" whose TTL matches the token lifetime, or a credential-version claim that is incremented whenever sessions are invalidated.
JWS (RFC 7515) signs the payload but leaves it readable: anyone holding the token can Base64URL-decode it and read every claim. JWE (RFC 7516) encrypts the content and has five segments instead of three, with a header that adds "enc" (for example A256GCM) alongside "alg". If the payload carries data that must stay hidden, you need JWE or you simply leave that data out.
Because verification runs over the exact bytes of the first two segments, not over the resulting JSON object. Decoding, pretty-printing and re-encoding changes whitespace, key order or "=" padding and feeds a different input to the HMAC. It also fails when the secret carries an invisible trailing space, or when a PEM public key was pasted without its BEGIN and END lines.