XConvert
Downloads
Pricing

Decode JWT Online

Paste or upload a JWT to decode it and view the token content in a readable format in seconds.

How to Decode a JWT Online

  1. Paste Your JWT: Copy the full token (three Base64URL segments separated by dots — header.payload.signature) and paste it into the input box. The decoder accepts JWS (signed) tokens only; encrypted JWE tokens require a private key and are not handled here.
  2. Inspect the Decoded Header and Payload: The tool splits on the dots and Base64URL-decodes the first two segments to JSON. The header reveals alg, typ, and optional fields like kid, jku, or x5c. The payload exposes every registered claim (iss, sub, aud, exp, nbf, iat, jti) and any custom claims your application added.
  3. Check Expiration and Audience (Optional): Convert the exp and iat Unix timestamps with the Timestamp to Date Converter to confirm the token is still within its validity window. Compare aud against your API's expected audience and iss against the trusted issuer URL.
  4. Read the Raw Signature: The third segment is displayed in its raw Base64URL form. Decoding does not verify it — that requires the issuer's secret (HMAC) or public key (RSA / ECDSA / EdDSA) plus a JWT library on the server side.

Everything happens in your browser session via client-side JavaScript. The token is never transmitted to xconvert or any third-party server, so you can safely inspect access tokens that contain user identifiers, scopes, or tenant data.

Why Decode a JWT?

JSON Web Tokens (RFC 7519) are the dominant token format for OAuth 2.0 access tokens, OpenID Connect ID tokens, API session credentials, and service-to-service authentication in microservice architectures. Because the header and payload are only Base64URL-encoded (not encrypted), anyone holding a JWS token can read its contents — that is by design, and it is exactly why a decoder is useful for debugging.

  • Debugging 401 / 403 responses — When an API rejects a request, decoding the bearer token reveals whether exp has passed, whether aud matches the resource server, and whether the granted scope covers the operation.
  • Inspecting OAuth provider tokens — Auth0, Okta, AWS Cognito, Azure AD, and Keycloak all issue access tokens as JWTs. Decoding shows the issuer URL, tenant ID, granted scopes, and any custom claims (roles, group memberships, feature flags) the provider injected.
  • Validating SSO claims — OpenID Connect ID tokens carry user identity in claims like sub, email, email_verified, and name. Decoding confirms the IdP sent what your app expects before you ship a relying-party integration.
  • Security review of issued tokens — Audit the alg field for weak algorithms (HS256 with a guessable secret, or none), confirm exp - iat is reasonable (15 minutes for access tokens, hours for refresh tokens), and check that no PII is leaked in claims that downstream services log.
  • Learning the spec — Pasting a real token and reading the parsed JSON is the fastest way to internalize how the three segments relate to RFC 7519 and the signing algorithms defined in RFC 7518 (JWA).
  • Tracking down stale kid rotation bugs — When key rotation breaks verification, the kid header value tells you which JWKS entry the token expects, so you can compare against the issuer's /.well-known/jwks.json.

JWT Registered Claims (RFC 7519 Section 4.1)

Claim Name Type Purpose
iss Issuer String / URI Principal that issued the JWT; usually the IdP's HTTPS URL.
sub Subject String / URI Principal the JWT is about; typically the user ID.
aud Audience String or string array Recipients the JWT is intended for; receivers MUST reject if not present.
exp Expiration Time NumericDate (Unix seconds) Token MUST NOT be accepted after this time.
nbf Not Before NumericDate (Unix seconds) Token MUST NOT be accepted before this time.
iat Issued At NumericDate (Unix seconds) Time at which the JWT was issued.
jti JWT ID String Unique identifier; used to prevent replay and enable revocation lists.

All seven are listed as optional but recommended in the spec. The aud, exp, and nbf validations are the ones servers most commonly get wrong — they are MUST-reject checks when the claims are present, not best-effort hints.

Common JWT Signing Algorithms (RFC 7518)

alg value Family Key type Notes
HS256 HMAC + SHA-256 Shared secret Simplest; secret must be high-entropy (≥32 bytes) and never leaked. Default in many quickstart guides.
HS384 / HS512 HMAC + SHA-384 / 512 Shared secret Stronger hash, otherwise identical to HS256.
RS256 RSA-PKCS#1 v1.5 + SHA-256 RSA key pair Public key can be published via JWKS; private key signs. Most common for OIDC and large public issuers.
RS384 / RS512 RSA + SHA-384 / 512 RSA key pair Stronger hash variants of RS256.
PS256 / PS384 / PS512 RSA-PSS RSA key pair Modern PSS padding; preferred over RS* when supported.
ES256 / ES384 / ES512 ECDSA + SHA-2 EC key pair (P-256 / P-384 / P-521) Smaller signatures and faster than RSA at equivalent strength.
EdDSA Edwards-curve DSA Ed25519 / Ed448 Defined in RFC 8037; modern, deterministic, side-channel resistant.
none (none) — Unsecured JWT. Tokens with alg=none MUST NOT be accepted by production verifiers.

When verifying, always pin the expected algorithm on the server side. Do not derive the algorithm from the incoming token's alg header — that is the entry point for the algorithm-confusion class of attacks (Auth0 disclosure, March 31, 2015; CVE-2015-9235 covers the RS256→HS256 variant in node-jsonwebtoken < 4.2.2).

Frequently Asked Questions

Does decoding a JWT verify the signature?

No. Decoding only Base64URL-decodes the first two segments and parses them as JSON. Anyone with the token can do this — that is why JWTs must be transmitted over TLS and treated as bearer credentials. Verification requires the signing key (HMAC secret for HS*, public key for RS* / ES* / EdDSA) and a vetted library (jsonwebtoken for Node.js, PyJWT for Python, jjwt for Java, golang-jwt/jwt for Go). The XConvert decoder is for inspection and debugging; it never asks for keys and never claims to validate authenticity.

Why can a JWT be decoded without the secret?

A JWS-signed JWT is encoded, not encrypted. RFC 7515 specifies Base64URL encoding for the header and payload, which is a reversible transform that exists to make the token URL- and HTTP-safe — it is not a cipher. The signature segment is the only part that depends on the key, and even that is a MAC or signature over the encoded bytes, not an encryption of them. If you need confidentiality, use JWE (see below) or move the sensitive data out of the token entirely.

Are JWTs encrypted?

JWS (RFC 7515) signed tokens are not — they provide integrity and authentication only, and the payload is readable by anyone holding the token. JWE (RFC 7516) tokens are encrypted with authenticated encryption (typically A256GCM or A128CBC-HS256) and require a decryption key to read. JWEs have five Base64URL segments separated by dots rather than three. If a token has five segments, this decoder will not handle it — use a server-side JWE library with the appropriate private key.

How dangerous is alg=none?

Critical. Auth0's original March 2015 disclosure documented multiple popular libraries that accepted tokens with "alg":"none" and an empty signature as valid, letting attackers forge arbitrary claims and impersonate any user. Modern libraries reject none by default, but the failure mode reappears whenever a verifier reads the algorithm from the incoming token instead of pinning it server-side. Defense: pass an explicit allowlist ({algorithms: ['RS256']} in jsonwebtoken, algorithms=["RS256"] in PyJWT) and never use the no-arg verify() form.

How do I validate exp and nbf correctly?

Both claims are NumericDate values — seconds (not milliseconds) since 1970-01-01T00:00:00Z UTC. Reject when now < nbf or now >= exp. RFC 7519 permits a small leeway (typically 30-60 seconds) to absorb clock skew between issuer and verifier; most libraries expose this as a clockTolerance or leeway option. Do not skip the check just because the token "looks fresh" — an absent exp paired with a missing leeway check is a long-lived token in disguise.

What is the kid header for?

kid (key ID) is an optional header parameter (RFC 7515 Section 4.1.4) that names which key in the issuer's key set was used to sign the token. Issuers publish their public keys at /.well-known/jwks.json — each entry has a matching kid. During key rotation, the issuer signs new tokens with the new kid while keeping the old key in the JWKS until existing tokens expire. Verifiers should look up the key by kid from a cached JWKS, not trust any URL the token itself points to (jku and x5u headers are spec-defined but operationally risky — pin the JWKS URL out of band).

How is JWT different from PASETO?

PASETO (Platform-Agnostic Security Tokens) was designed in 2018 specifically to remove JWT's footguns. Its versioned protocols (v4.public, v4.local) hard-code a single modern algorithm — Ed25519 for signed public tokens, XChaCha20-Poly1305 for symmetric local tokens — so there is no alg header to confuse, no none algorithm, and no negotiation. Trade-offs: PASETO has narrower ecosystem support, no JWKS equivalent, and is not understood by external IdPs like Auth0 or Okta. Pragmatic split many teams adopt: keep JWT for federated OIDC where compatibility is mandatory, use PASETO (or signed cookies) for first-party service-to-service tokens you control end-to-end.

Why does my payload show numbers instead of dates for exp and iat?

Both are NumericDate values measured in Unix seconds (RFC 7519 Section 2). For example, 1735689600 is 2025-01-01T00:00:00Z. Pipe the value through the Timestamp to Date Converter for a readable date, or in code use new Date(exp * 1000) (JavaScript) or datetime.fromtimestamp(exp, tz=timezone.utc) (Python). The seconds-not-milliseconds distinction trips up developers porting from JavaScript's Date.now() constantly — multiplying by 1000 too many or too few times is the most common timestamp bug in JWT code.

Can I edit the decoded payload?

The XConvert JWT Decoder is read-only. Changing any byte of the header or payload invalidates the signature, so the verifier will reject the modified token unless you re-sign it with the issuer's key (which you should not have). If you need test fixtures with custom claims, use a JWT library that issues new tokens, or generate them with a tool that controls the signing key — never try to "edit" a production token.

Related tools: Base64 Decoder · JSON Formatter · Unix Timestamp to Date · URL Decoder · HTML Entity Decoder

Image Tools

Image CompressorCompress JPEGCompress PNGCompress GIFCompress WebPImage ConverterJPG ConverterImage Resizer

Video Tools

Video CompressorCompress MP4MP4 to GIFVideo to GIFVideo ConverterMP4 ConverterVideo Cutter

Audio Tools

Audio CompressorCompress MP3Compress WAVAudio ConverterMP3 ConverterFLAC to MP3Audio Cutter

Document Tools

Compress PDFMerge Images to PDFSplit PDFPDF to JPGUnzip FilesRAR Extractor
© 2026 XConvert.com. All Rights Reserved.
About UsPrivacy PolicyTerms of ServiceContactHelp Us Grow