JWT Generator
Create signed JSON Web Tokens with HMAC (HS256–512), RSA, RSA-PSS, ECDSA or EdDSA for development and testing — keys are generated and used only in your browser.
How to use this tool
Steps for using the JWT Generator.
- Pick an algorithm family — HMAC, RSA, RSA-PSS, ECDSA or EdDSA — and the hash size (256, 384 or 512). The token is signed as you type.
- Edit the payload JSON. Use iat = now, nbf = now and exp = now + 1h (or any duration like
15mor7d), and Add claim foriss,aud,sub,scopeor a randomjti. Time claims are shown as dates with how long until they expire. - For HMAC, enter a test secret or click Random 256-bit / Random 512-bit; turn on Secret is Base64 when the secret is encoded binary. For the other families, click Generate key pair or paste your own PKCS#8 private key or private JWK.
- Optionally set a Key ID (kid) and typ for the header. With asymmetric keys, copy or download the public key as PEM or JWK for the service that verifies tokens (and
private.pemif you need it). - Check the colour-coded token, the decoded header and payload, and the self-check that verifies the signature. Copy the token into your API client, test suite or the JWT Decoder.
Example
Reproduce the jwt.io HS256 example
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1516239022
}eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5cCommon use cases
- Creating tokens with specific claims to test authorization rules in a local API.
- Producing an already-expired or not-yet-valid token to test error handling.
- Generating fixtures for integration tests that use a known development secret.
- Checking that your backend's HS256 implementation produces the same signature for the same input.
- Learning how header, payload and signature fit together by changing claims and watching the token change.
How HMAC-signed JWTs are built
A signed JWT is base64url(header) + "." + base64url(payload) + "." + base64url(signature). The header and payload are serialised as compact JSON and encoded with URL-safe Base64 without padding. For the HS family the signature is an HMAC of the ASCII string header.payload — HMAC-SHA-256 for HS256, SHA-384 for HS384 and SHA-512 for HS512 — computed here with the browser's Web Crypto API (crypto.subtle.importKey and crypto.subtle.sign).
HMAC is symmetric: the same secret signs and verifies. Every service that verifies the token can therefore also mint new tokens, and anyone who learns the secret can forge tokens for any user. RFC 7518 requires a key at least as long as the hash output — 256 bits for HS256, 384 for HS384, 512 for HS512 — and it should be random bytes, not a memorable phrase. The tool warns when a secret is shorter; the jwt.io sample secret your-256-bit-secret, despite its name, is only 19 bytes (152 bits).
A token being signed does not make a system secure. Security comes from a strong secret kept on the server, short expiry times (exp minutes or hours ahead, not years), full validation on every request (signature, an allow-list of algorithms, exp, nbf, iss and aud), and transporting tokens only over HTTPS. Treat any token produced here as test data.
When several services need to verify tokens but only one should issue them, asymmetric algorithms such as RS256 or ES256 are a better fit: the issuer signs with a private key and verifiers only hold the public key. Those algorithms are deliberately not offered here, because pasting private keys into a web page is a habit worth avoiding.
Limitations
- Only HMAC algorithms (HS256, HS384, HS512) are supported; RS256, ES256, PS256 and EdDSA are not.
- Header parameters other than
algandtyp(such askid) cannot be added. - The payload is re-serialised as compact JSON, so key order is preserved but whitespace is not.
- For development and testing only — do not use production secrets in any online tool.
Frequently asked questions
Is the secret sent anywhere?
No. Signing uses the Web Crypto API inside your browser and nothing is uploaded or logged. It is still bad practice to paste production secrets into any website, so use development secrets only.
How long should an HS256 secret be?
At least 256 bits (32 bytes) of cryptographically random data. Use Generate random secret for a 32-byte value, or produce one with openssl rand -base64 32. Human-chosen passphrases are far weaker than their length suggests and can be brute-forced from a single token.
Why does my library produce a different signature?
Usually the secret is interpreted differently: some libraries treat the secret as Base64 and decode it, others use its UTF-8 bytes. Toggle Secret is Base64-encoded to match. Different JSON whitespace or key order in the payload also changes the signature.
Does a generated token prove anything about security?
No. A JWT is only as trustworthy as the secret behind it and the validation your server performs. Short expiry, strict validation of alg, exp, aud and iss, and HTTPS matter more than the token itself.
Can I set exp in milliseconds?
You should not. JWT time claims are seconds since the Unix epoch; the helper buttons write seconds. A millisecond value would make the token valid for tens of thousands of years.