JWT Generator
Create JSON Web Token with custom Header and Payload
What is JWT?
The JWT Generator creates JSON Web Tokens from a header, payload, and signing settings. A JWT has three Base64URL-encoded parts and is commonly used to carry claims such as user ID, roles, expiration time, issuer, and audience between services. This tool helps with API testing, local development, education, debugging, and quickly producing example tokens. A generated token is only trustworthy when key management, algorithm choice, expiration, and server-side validation are handled correctly. Secrets should not be pasted into public examples, weak algorithms or overly long lifetimes are risky, and sensitive personal or business data should not be placed in an unencrypted payload.
How to Use
JWT Generation Flow
- Select signing algorithm (default HS256)
- Enter or click "Generate" to create a signing secret
- Edit Payload JSON, use quick add buttons to add standard claims
- Set issued at (iat) and expiration (exp) time
- Click "Generate JWT Token" button
- Copy the generated Token for testing or development
Token Safety
- Use strong secrets for HMAC algorithms and protect private keys for RSA/ECDSA algorithms.
- Set realistic exp, iat, issuer, and audience claims; a syntactically valid JWT can still be insecure or rejected by your service.
Use Cases
Technical Principle
The JWT generator and parser are inverse processes: parsing takes the three parts apart, generating assembles them. The core is computing the Signature segment. Assembly flow: 1) Build the Header JSON, e.g. {"alg":"HS256","typ":"JWT"}; 2) Build the Payload JSON with standard and private claims; 3) Base64URL-encode Header and Payload separately to get h_b64 and p_b64; 4) Join h_b64 and p_b64 with a period to form input = h_b64 + '.' + p_b64; 5) Compute the signature: HMAC-SHA256/384/512(secret, input) depending on alg; 6) Base64URL-encode the signature result; 7) The final token is input + '.' + sig_b64. HMAC-SHA256 signing: use the secret as the key (>= 32 bytes) and run HMAC over the input. Internally HMAC runs two SHA-256 rounds: the secret first derives ipad/opad keys, then SHA256(secret XOR ipad || msg) XOR opad. Key strength: secret length directly determines security. RFC 7518 requires HS256 keys to be >= 256 bits (32 bytes). In production always use a cryptographically secure RNG (e.g. crypto.randomBytes); never use strings like 'secret', 'password', or '123456'. Common pitfalls: 1) alg-substitution attack: the server must strictly validate alg, and must not read alg from the token header and dispatch to the matching algorithm; 2) Weak keys: a too-short secret can be brute-forced; 3) Payload tampering: HMAC guarantees integrity - if an attacker changes the payload, server-side verification fails; 4) Token leak: JWTs cannot be revoked, so once a token is out, the only fix is to wait for it to expire. Scope of this tool: only HS256/HS384/HS512 are generated. Asymmetric algorithms such as RS256 (RSA) and ES256 (ECDSA) require a private key kept on the issuer side and are produced by a backend signing service or a dedicated SDK, not by this page.
- HMAC-SHA256 signing core: HMAC(secret, header_b64 + '.' + payload_b64), output a 256-bit signature and Base64URL-encode it.
- HS256 key length must be >= 32 bytes (256 bits); recommend generating with crypto.getRandomValues or crypto.randomBytes - short keys are vulnerable to dictionary attacks.
- This tool only generates HMAC-signed tokens (HS256/HS384/HS512). Asymmetric algorithms such as RS256 or ES256 require a private key kept on the issuer side and are not produced here — use a backend signing service or a dedicated SDK for those.
- iat/exp/nbf are all Unix timestamps in seconds (not milliseconds); servers usually require exp > now(), nbf <= now(), and iat <= now().
- alg=none attack: maintain a server-side whitelist of allowed algorithms (e.g. ['HS256']); never pick the algorithm dynamically from the token header. Many JWT libraries historically allowed alg=none by default - that's a known vulnerability.
- A JWT cannot be revoked once issued - the only recourse is to wait for exp. For active revocation, maintain a jti blacklist or use a short-lived access token plus a refresh token.
Examples
Basic HS256 Example
Header: {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"user-123","name":"Alice","role":"admin","iat":1705312800,"exp":1705399200}
Secret: my-super-secret-key-32-bytes-long
Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTEyMyIsIm5hbWUiOiJBbGljZSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcwNTMxMjgwMCwiZXhwIjoxNzA1Mzk5MjAwfQ.7Hk2L9oP3qR1mN4vK8xJ2wE5yT6sB0fA9cZ1dG3hI4UCustom expiration with iat and exp
Header: {"alg":"HS256","typ":"JWT"}
Payload: {"iss":"https://auth.example.com","sub":"user-456","aud":"api.example.com","iat":1705312800,"exp":1705316400}
Secret: another-strong-secret-32-bytes-long
The page Base64URL-encodes header and payload, joins them with a dot, then runs HMAC-SHA256 over the result with the shared secret. The Token field shows the final three-segment string ready to paste into Authorization headers.Custom Claims
Header: {"alg":"HS256","typ":"JWT"}
Payload: {
"sub": "user-789",
"name": "Bob",
"role": "editor",
"tenant": "acme-corp",
"permissions": ["read:docs", "write:docs"],
"scope": "docs.read docs.write",
"iat": 1705312800,
"exp": 1705399200,
"jti": "550e8400-e29b-41d4-a716-446655440000"
}FAQ
Is the JWT generated locally?
Yes. The header, payload, and signature are computed in your browser using the Web Crypto API. The signing secret or private key never leaves the page. Treat the token itself as data that may be logged or exposed, especially if you paste it into a real service.
Which signing algorithms are supported?
This tool generates HS256, HS384, and HS512 (HMAC with a shared secret). Asymmetric algorithms such as RS256/RS384/RS512 (RSA) and ES256/ES384/ES512 (ECDSA) are not produced here — use a backend signing service or a dedicated SDK if your verifier expects them. Avoid alg=none in production: any sane verifier rejects unsigned tokens.
What goes in the payload?
Standard claims like sub, iss, aud, exp, iat, nbf plus any custom claims your service uses. Keep the payload small - JWTs travel in headers and grow every request. Never put passwords, full credit card numbers, or other secrets inside; the payload is Base64URL, not encrypted.
How do I set the expiration time?
Set exp to the Unix timestamp (seconds, not milliseconds) at which the token should stop being valid. Tokens with no exp are technically legal but most production services insist on one. Common values are 5-60 minutes for access tokens, 7-30 days for refresh tokens.
Why does my generated JWT fail verification?
Common causes: alg in the header does not match what the verifier expects; secret/key is different; payload claims (iss, aud) do not match server config; clock skew between issuer and verifier exceeds the allowed leeway (typically ±60 s); a manual edit broke the Base64URL encoding (don't add line breaks).
Is my secret or private key sent to a server?
No. Signing happens entirely in the browser via Web Crypto. That said, never paste a production signing key into any web tool - test with a non-production key, then sign in your real backend.
Should I use HS256 or RS256?
HS256 needs both sides to share a secret, so it only fits situations where the same service issues and verifies the token. RS256 (or ES256) lets the issuer keep a private key while every consumer verifies with the public key - the right choice for OAuth/OIDC and any multi-service architecture. This tool only generates HS-family tokens; for RS256/ES256, use a backend signing service or a dedicated SDK.