Auth Tools
JWT Generator
Build and sign a JWT with HS256, HS384, HS512, or RS256, using a test key that never leaves your browser.
Understand the format
How JWT Generator works
Signing a JWT is three steps: Base64URL the header, Base64URL the claims, then sign those exact bytes with a key the verifier already trusts.
What the signature actually covers
A signed JWT is header.payload.signature, and the signature is computed over the ASCII string formed by the first two segments joined with a dot. Nothing else is included: not the whitespace of your original JSON, not the order you typed the claims in, only the encoded bytes. That is why this page shows the signing input alongside the token, because it is the value your verifier will reconstruct and check.
It also explains a common confusion. Re-encoding the same claims with different key order or spacing produces a different signing input and therefore a completely different signature, even though the decoded claims are identical. A JWT is not canonical; it is a specific byte sequence with a signature attached.
Symmetric and asymmetric algorithms
HS256, HS384, and HS512 are HMAC with a shared secret: the same value both signs and verifies. That is fine when one service does both, and a poor fit when many services must validate tokens, because every verifier would also be able to mint them. The secret should be long random bytes, not a memorable phrase; HS256 uses a SHA-256 HMAC, so at least 256 bits of key material is the sensible target.
RS256 signs with an RSA private key and verifies with the matching public key, usually published as a JWKS document. Verifiers then need no secret at all, which is what makes it the default for identity providers. This page accepts an unencrypted PKCS#8 private key; if your file begins with BEGIN RSA PRIVATE KEY it is PKCS#1 and needs converting first with openssl pkcs8 -topk8 -nocrypt.
The algorithm confusion attack
Historically, libraries chose the verification algorithm by reading the alg header of the token being checked. An attacker could set alg to none and strip the signature, or change RS256 to HS256 and sign with the public key as if it were an HMAC secret, since that key is published. Both produce tokens that vulnerable verifiers accept.
The fix belongs on the verifying side: configure the expected algorithm and reject anything else, rather than trusting the header. RFC 8725 collects this and the rest of the current best practice. When you generate a test token here, changing the algorithm changes the header, which makes it a useful way to check that your verifier rejects what it should.
Claims worth setting on a test token
A realistic test token needs the claims your verifier checks, not just a subject. Set iss and aud to match the service configuration, exp to a near-future time, and iat to now. Tokens that omit exp never expire, which is convenient in a fixture and dangerous if one escapes into a shared environment.
Keep the payload small and public. Claims are only encoded, never encrypted, so anyone holding the token can read them; a JWT is the wrong place for anything the bearer should not see.
Step by step
How to use JWT Generator
- Pick the algorithm your verifier is configured to accept.
- Paste a throwaway signing secret, or a PKCS#8 PEM private key when using RS256.
- Edit the claims as JSON, then press "Set iat and exp from now" so the token is valid from this moment.
- Add a kid header when your verifier selects among several keys from a JWKS.
- Copy the token and check it in the JWT Decoder, then confirm your backend accepts or rejects it as you expect.
The header, claims, and signature are produced in your browser with the Web Crypto API. No secret, private key, or token is transmitted or stored, and nothing is generated during server rendering.
Troubleshooting
Common mistakes and how to fix them
- Signing with a short, human-chosen HMAC secret.
- A guessable secret can be brute-forced offline from a single captured token. Use at least 256 bits of random key material.
- Putting personal data or internal identifiers in the claims.
- The payload is encoded, not encrypted. Anyone with the token reads it. Keep sensitive data server-side and reference it by id.
- Writing exp in milliseconds.
- RFC 7519 time claims are seconds since the epoch. Milliseconds put the expiry tens of thousands of years out, so the token never expires.
- Reusing a production signing key to generate test tokens.
- A test token signed with the production key is a production credential. Keep separate keys per environment.