Decode claims without confusing them with trust
A signed JWT contains Base64URL-encoded header and payload segments followed by a signature. Decoding the first two segments only reveals JSON; anyone can create or edit those bytes. This tool therefore keeps structural decoding, claim-time checks, and cryptographic signature verification as separate results.
The claims breakdown recognizes iss, sub, aud, exp, nbf, iat, and jti. NumericDate values are rendered as local dates, while exp and nbf are compared with the current browser time. Audience, issuer, application policy, revocation, and server clock skew still belong to the receiving system.
Verify the algorithm declared by the token
Optional verification supports HMAC SHA-2 (HS256/384/512), RSA PKCS#1 v1.5 (RS256/384/512), RSA-PSS (PS256/384/512), and ECDSA (ES256/384/512) through the browser Web Crypto API. HMAC uses a shared secret; RSA and ECDSA verification use a PEM public key.
A verified signature proves only that the signing input matches the supplied key under the declared supported algorithm. It does not establish who supplied that key, whether the issuer is trusted, whether the token is revoked, or whether its claims are acceptable for your application.
Common failures this tool explains
- The token does not contain exactly three dot-separated JWS segments.
- The header or payload is not Base64URL-encoded UTF-8 JSON object data.
- The declared alg is unsupported or the supplied key type does not match it.
- The signature is correct but exp, nbf, issuer, audience, or application policy still rejects the token.
Equivalent commands
Use the runtime or shell already available in your workflow. Validate untrusted input and keep binary output out of terminals.
Python
import base64, json
h, p, s = token.split('.')
decode = lambda value: json.loads(base64.urlsafe_b64decode(value + '=' * (-len(value) % 4)))
print(decode(h), decode(p))
JavaScript
const [header, payload] = token.split('.');
const decode = value => JSON.parse(Buffer.from(value, 'base64url').toString('utf8'));
console.log(decode(header), decode(payload));
Shell
IFS=. read -r header payload signature <<EOF
$TOKEN
EOF
printf '%s' "$payload" | basenc --base64url --decode