How JWT Decode Works
How Decoding Works
When you paste a JWT, the tool immediately splits the token on the . character to find the three segments. It then Base64url-decodes the header and payload segments into UTF-8 strings and parses them as JSON. This is pure string manipulation — no network requests, no cryptography.
// Simplified decoding logic
function decodeJwt(token) {
const [headerB64, payloadB64, signature] = token.split('.')
const header = JSON.parse(base64urlDecode(headerB64))
const payload = JSON.parse(base64urlDecode(payloadB64))
return { header, payload, raw: { headerB64, payloadB64, signature } }
}
function base64urlDecode(str) {
// Replace url-safe chars, add padding, then decode
const b64 = str.replace(/-/g, '+').replace(/_/g, '/')
const padded = b64.padEnd(b64.length + (4 - b64.length % 4) % 4, '=')
return new TextDecoder().decode(
Uint8Array.from(atob(padded), c => c.charCodeAt(0))
)
}The decoded header and payload objects are then passed to the various view components (Decoded, Claims, Raw) which render them using React. The decoding runs synchronously on every keystroke — there is no debounce or async operation involved.
How Signature Verification Works
When you use the Verify tab, the tool uses the browser's window.crypto.subtle API — the Web Crypto API — to perform the cryptographic signature check. This API is a native browser capability; no JavaScript cryptography library is used.
HMAC (HS256/HS384/HS512)
For HMAC algorithms, the tool imports the secret as a raw key into the Web Crypto API and computes HMAC-SHA{256|384|512} over the signing input (headerB64 + "." + payloadB64), then compares the result to the token's signature using a constant-time comparison.
// HMAC verification (pseudocode)
const key = await crypto.subtle.importKey(
'raw',
textEncoder.encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['verify']
)
const sigBytes = base64urlToBytes(signatureB64)
const signingInput = textEncoder.encode(headerB64 + '.' + payloadB64)
const isValid = await crypto.subtle.verify('HMAC', key, sigBytes, signingInput)RSA (RS256/RS384/RS512/PS256/PS384/PS512)
For RSA and RSA-PSS algorithms, the tool parses the PEM public key you provide, extracts the DER-encoded key bytes, imports them via crypto.subtle.importKeywith the SPKI format, and then calls crypto.subtle.verify.
ECDSA (ES256/ES384/ES512)
For ECDSA, the tool follows the same pattern but uses the EC algorithm family with the appropriate named curve (P-256, P-384, P-521).
window.crypto.subtle, which runs in the browser's secure runtime. No keys are transmitted. No custom cryptography is implemented — only standard Web Crypto API calls.Privacy Architecture
The tool is deliberately designed so that token data cannot reach the server:
- ·Static site: The site is served as a static HTML/CSS/JS bundle from a CDN-backed server. There is no application server that receives request bodies. The server only receives HTTP requests for static asset files.
- ·No form submissions: Token input is an HTML textarea whose value is never submitted to the server. It is handled entirely by React event handlers running in the browser.
- ·No URL parameters: Token content is never embedded in the URL, so it cannot appear in server access logs or browser history.
- ·No external API calls for token processing: The JavaScript code makes no fetch or XMLHttpRequest calls with token content. The only outbound network requests from the page are for fonts (Google Fonts) and advertisements (Google AdSense), neither of which receives any JWT data.
- ·Memory-only state: Token content lives only in React component state. It is not written to localStorage, sessionStorage, IndexedDB, or cookies. Closing the tab clears all token data.
Tool Limitations
- ·JWE (encrypted JWTs) not supported: JSON Web Encryption tokens have a different structure from plain JWTs (JWS). They have five segments and require a decryption key. This tool decodes JWS tokens only — if you paste a JWE token, it will appear malformed since the encrypted structure cannot be decoded without the decryption key.
- ·Verification is for inspection only: Client-side verification using this tool is suitable for debugging. It is not a substitute for server-side verification in a trusted environment. The security model for authorization decisions requires server-side verification with a trusted JWT library.
- ·Key format requirements: For RSA and EC verification, public keys must be in PEM SPKI format (
-----BEGIN PUBLIC KEY-----). PKCS#1 (-----BEGIN RSA PUBLIC KEY-----) is not supported by the Web Crypto API's SPKI import format. - ·alg=none: Tokens with
alg=noneare flagged as unsecured. The Verify tab will show an appropriate warning — these tokens have no cryptographic signature to verify.