1. RFC 7519 JSON Web Token Anatomy
JSON Web Token (RFC 7519) is an open, URL-safe standard facilitating compact, verifiable data exchange between client applications and backend APIs.
Every JWT comprises three dot-separated components: Header, Payload, and Signature. Crucially, the header and payload are merely Base64URL-encoded strings, not encrypted data. Security is maintained strictly through the cryptographic signature.
// 1. Header (Specifies signing algorithm and type)
{
"alg": "HS256",
"typ": "JWT"
}
// 2. Payload (Claims and metadata)
{
"sub": "usr_94819284",
"name": "Jane Doe",
"role": "admin",
"iat": 1730000000,
"exp": 1730003600
}
// 3. Signature Construction
// HMACSHA256(base64Url(header) + "." + base64Url(payload), secretKey)2. HMAC Symmetric vs RSA/ECDSA Asymmetric Signing
Symmetric algorithms (HS256, HS384) use a shared secret for both signing and verification, ideal for single-server architectures.
Asymmetric algorithms (RS256, ES256) employ public/private key pairs. The authorization server signs tokens with its private key, while downstream microservices verify authenticity using only the public key.
| Attribute | HMAC (HS256) | RSA (RS256) | ECDSA (ES256) |
|---|---|---|---|
| Key Type | Shared Secret (Symmetric) | Public / Private Key Pair | Elliptic Curve Public / Private Pair |
| Signature Size | Compact (32 bytes) | Large (256 - 512 bytes) | Very Compact (64 bytes) |
| Verification Speed | Extremely Fast | Fast | Fast |
| Best Use Case | Single Backend API | Distributed Microservices, OAuth 2.0 | High-Throughput Mobile APIs |
3. Common Vulnerabilities and Threat Mitigations
1. The 'alg: none' Exploit: Legacy libraries that blindly honor 'alg': 'none' allow attackers to forge valid tokens with administrative privileges without knowing the secret. Always enforce explicit algorithm whitelisting.
2. Weak Secret Brute-Forcing: Predictable shared secrets are easily cracked using hashcat dictionary attacks. Always generate keys with at least 256 bits of entropy.
4. In-Browser Verification via W3C Web Crypto API
Our JWT Debugger verifies HMAC signatures directly within client memory using the native Web Crypto API:
async function verifyJwtHs256(token, secret) {
const [headerB64, payloadB64, signatureB64] = token.split('.');
const dataToVerify = new TextEncoder().encode(`${headerB64}.${payloadB64}`);
const key = await window.crypto.subtle.importKey(
'raw',
new TextEncoder().encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['verify']
);
const rawSignature = Uint8Array.from(atob(signatureB64.replace(/-/g, '+').replace(/_/g, '/')), c => c.charCodeAt(0));
return await window.crypto.subtle.verify('HMAC', key, rawSignature, dataToVerify);
}5. Safe Storage: HttpOnly Cookies vs LocalStorage
Never store access tokens in browser LocalStorage where any Cross-Site Scripting (XSS) vulnerability can exfiltrate them. Always store authentication tokens in HttpOnly, Secure, SameSite=Strict cookies.