🏷 JWT Generator
Mint signed HS256, HS384, or HS512 test tokens with the WebCrypto API on this page, so the secret you type never reaches a server.
Last updated: June 9, 2026 · By Λ
By Λ · Updated June 9, 2026 · ~3 min read
What this tool is for
Generates symmetric-key (HMAC) JSON Web Tokens with HS256, HS384, or HS512. The tool is most useful when you need to mint a test JWT to paste into Postman, curl, or your API test suite. For asymmetric signing (RS256, ES256), you need keypair handling that does not fit cleanly on a single page; use a library in your backend.
Standard claims (RFC 7519)
iss(issuer): who issued the tokensub(subject): the user/entity the token is aboutaud(audience): who the token is intended forexp(expiration): unix timestamp when the token expiresnbf(not before): unix timestamp before which the token is invalidiat(issued at): unix timestamp when the token was issuedjti(JWT ID): unique identifier for the token (useful for revocation)
When NOT to use JWT
For session tokens. Use opaque random tokens stored server-side. JWTs cannot be revoked without a server-side allowlist, which defeats their purpose.
For sensitive data. The payload is base64-encoded, not encrypted. Anyone with the token can read it.
For long-lived auth. JWTs that live for days are a security smell. Issue short-lived access tokens (15 min) plus opaque refresh tokens.
Picking an algorithm
HS256 (HMAC-SHA256) is the default and fine for most use cases. HS384/HS512 give slightly more output bits but no real security benefit for tokens. RS256/ES256 (asymmetric) is the right choice when you have multiple services verifying tokens but only one minting them; the others only need the public key.
How the generator works
Press Generate Token and the page parses both JSON boxes, forces the header's alg to match the dropdown, and restores typ if you deleted it. Both parts are serialized compactly, base64url-encoded with padding stripped, then HMAC-signed as header.payload through crypto.subtle. Any auto-set choice besides Manual stamps iat with the current clock, pushes exp one hour to thirty days out, and writes both back into the payload box. The presets cover common payload shapes: user session (email, name, role), api access (a scope string), refresh token (random jti via crypto.randomUUID()), and minimal (just sub). A starter token is minted from the sample values on page load.
Worked example
With the defaults untouched (HS256 header, the user_123 payload, secret your-256-bit-secret), the output is always:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsIm5hbWUiOiJBbGljZSIsImlhdCI6MTcxNjAwMDAwMCwiZXhwIjoxNzE2MDAzNjAwfQ.K66FtZyXhSqqcBu7Pmvom4Dj55dgGOWgftgHyQeUxeE
HMAC is deterministic: those inputs reproduce this exact string anywhere, while one changed character in the secret rewrites the whole third segment.
Edge cases worth knowing
The dropdown beats a hand-edited alg value; the header is overwritten before signing. The secret is read as plain UTF-8 text; servers that base64-decode their key before verifying will reject tokens minted here until you paste the decoded form. exp and iat are unix seconds, so a 13-digit millisecond timestamp yields a token valid for thousands of years. Malformed JSON in either box prints the parser error in place of a token.
Frequently Asked Questions
Why does another tool say my signature is invalid?
Usually the secret is being treated differently. This page signs the literal bytes you typed, so untick any secret-is-base64 option on the other side and match the algorithm.
Can I generate RS256 or ES256 tokens here?
No. Only the three HMAC variants are offered; asymmetric signing needs keypair and PEM handling that belongs in a backend library.
Why did my payload change after generating?
An auto-set choice other than Manual overwrites iat and exp with fresh values and saves them into the editor before signing.
Related
For decoding existing tokens, see the JWT decoder. For Basic auth headers, see basic-auth-header. For password hashing, see bcrypt generator and the 2026 hashing guide.