JWT Generator

Your secret is used only in this page and is never sent anywhere, stored, or added to the URL — so a shared link cannot leak it. Never paste a production signing secret into any website, including this one; use a throwaway secret for testing.

Only HS256, HS384 and HS512 are supported. RS, ES and PS signing needs a private key, which this tool deliberately does not ask for.

Nothing you enter here is stored, logged or shared.

Build a JWT payload, pick an algorithm and sign it with your secret. Signing happens entirely in your browser, so the secret never leaves your device.

How to use

  1. Edit the payload as JSON.
  2. Optionally choose an expiry, which adds iat and exp for you.
  3. Enter your secret; the signed token appears below.

What signing produces

A JWT is three base64url segments joined by dots. The first is the header, saying which algorithm was used. The second is the payload, holding your claims. The third is the signature, computed over the first two segments joined by a dot - and it is the exact bytes of those segments that are signed, not the JSON they decode to, which is why re-serialising a token invalidates it.

With HS256 the signature is an HMAC of that signing input under your secret. Anyone holding the same secret can recompute it and see whether it matches, which proves two things: the token was issued by someone who knew the secret, and nothing in it has been altered since. Change a single character of the payload and the recomputed signature no longer agrees.

What it does not do is hide anything. The payload is encoded, not encrypted, and anyone who has the token can read every claim in it without the secret. Never put a password, a card number, or anything else you would not print in a log into a JWT payload.

Choosing a secret

RFC 7518 requires an HMAC key of at least the size of the hash output: 256 bits for HS256, 384 for HS384, 512 for HS512. That means 32 random bytes at minimum, not a memorable phrase.

The reason is that a JWT is an offline attack in a bottle. It contains the signing input and the signature together, so anyone who obtains one token can try candidate secrets against it as fast as their hardware allows, with no network round trip and nothing to rate-limit them. There are published tools that do exactly this, and a dictionary word or a short string falls in seconds. A leaked token with a weak secret means the attacker can mint their own tokens with any claims they like.

Use a random value from a password manager or a key generator, keep separate secrets per environment so a token from staging cannot be replayed against production, and rotate them the way you would any other credential.

The claims worth setting

Beyond whatever your application needs, RFC 7519 registers a small set of standard claims. iss names the issuer, sub identifies the subject, aud names the intended audience, and jti gives the token a unique id so it can be individually revoked or checked for replay. The three time claims - exp for expiry, nbf for the earliest valid moment, iat for issuance - are NumericDate values, meaning seconds since the Unix epoch.

Seconds, not milliseconds. Supplying a JavaScript timestamp directly is the single most common reason a hand-written token is rejected: an exp thirteen digits long parses as a date far in the future, which some libraries reject outright and others accept as a token that never expires.

Setting exp does not by itself make a token expire. It expires because the verifier checks the claim, and a verifier that only checks the signature will happily accept a token from last year. Most libraries also allow a small clock-skew tolerance, typically a minute or two, since the issuing and verifying machines rarely agree exactly.

Why only the HS algorithms, and the alg trap

The HS family is symmetric: one shared secret both signs and verifies, so signing can happen here with only what you type in. RS, ES and PS are asymmetric and would require pasting a private key into a web page, which is not a thing this tool is willing to ask for.

The header field that names the algorithm is also where two well-known attacks live. The first is alg: none, which declares the token unsigned; libraries that honoured it could be handed forged tokens with an empty signature. The second is algorithm substitution: take a token signed with RS256, change the header to HS256, and sign it with the issuer's public key as the HMAC secret. A verifier that reads the algorithm out of the token rather than deciding in advance will verify it happily, because the public key is not secret.

The defence in both cases is the same and belongs in your verifier, not your issuer: pin the expected algorithm in the verification call and reject any token whose header disagrees.

Designing the lifetime of a token

The single most consequential choice in a token system is how long a token lives, because a JWT cannot be withdrawn before it expires. Short lifetimes - five to fifteen minutes for an access token - keep the window of a leaked token small and are the standard answer, paired with a longer-lived refresh token that can be revoked because the server stores it.

Refresh token rotation makes that pairing meaningfully safer: each refresh issues a new refresh token and invalidates the old one, so a stolen token is usable once. If the old one is presented again, the server has learned that two parties hold it and can revoke the whole family.

Where a genuinely long-lived credential is needed - a machine integration, a CLI - a JWT is usually the wrong shape. An API key checked against a database can be revoked instantly, scoped precisely, and shown in an interface where its owner can see when it was last used.

Keys, rotation and the kid header

A signing key should be rotatable without an outage, and the mechanism is the kid header: the issuer names which key signed the token, and the verifier looks that key up rather than assuming. With HS256 that means a small map of key identifiers to secrets; with RS256 or ES256 it means a JWKS document the verifier fetches and caches.

Rotation then has three phases. Publish the new key so verifiers know it, switch signing to the new key while still accepting the old one, and retire the old key after every token signed with it has expired. Skipping the overlap is what turns a routine rotation into an incident.

Asymmetric algorithms are worth the extra setup as soon as more than one service verifies your tokens. With HS256 every verifier holds a secret that can also sign, so any compromised service can mint tokens; with RS256 the verifiers hold only a public key and cannot forge anything.

What belongs in the payload, and what does not

A token is a bearer credential that travels in a header on every request, so size has a real cost - proxies commonly cap headers at 8 KB, and a bloated token is paid for on each call. Keep it to identity and the few facts the verifier needs: subject, issuer, audience, expiry, and a small set of scopes or roles.

Anything volatile is a poor fit. Permissions baked into a token are stale from the moment they are issued, so a role revoked at 10:00 is still asserted by tokens until they expire. Where that matters, the token should carry identity and the service should look up authorisation, or lifetimes should be short enough that the staleness is acceptable.

Nothing secret belongs in there at all. The payload is encoded, not encrypted, so anyone holding the token can read every claim: no internal notes, no personal data beyond what the recipient needs, no keys. If a payload genuinely must be confidential, that is JWE, a different specification with different tooling.

Testing tokens without leaking anything

A generator is most useful for building fixtures: a token that is expired, one that is not yet valid, one with the wrong audience, one signed with the wrong key. A verification routine should be tested against all four, and most bugs in this area are cases where one of them is accepted.

Use a test secret, never a production one. It is the same argument as for any credential, and it is sharper here because a token and its signature together are enough for an offline attack on the secret. Separate secrets per environment also prevent the subtler failure where a token minted in staging is accepted in production.

Everything on this page runs in the browser, so nothing typed here is transmitted or stored. That is worth knowing given what people paste into token tools, and it is also why the asymmetric algorithms are absent: signing with RS256 would mean pasting a private key into a web page, and no tool should be asking for that.

Common reasons a hand-built token is rejected

Time claims in milliseconds are the most frequent. NumericDate is seconds since the epoch, so a thirteen-digit exp is read as a date tens of thousands of years away - rejected outright by some libraries, accepted as an eternal token by others, and neither is what you wanted.

Padding comes next. JWT segments use base64url without padding, so a token whose segments end in equals signs, or which contains plus and slash characters instead of minus and underscore, was encoded with the wrong alphabet and will fail before the signature is even checked.

The rest are usually mismatches. The audience the verifier expects differs by a trailing slash; the issuer is written with http where the verifier has https; the clock on one machine is a few minutes off and there is no skew tolerance configured. When a token decodes correctly and still fails, compare the claims against the verifier's configuration field by field before suspecting the signature.

Frequently asked questions

Is it safe to enter my signing secret?
The secret is used only by JavaScript on this page. It is never transmitted, stored, or written into the URL, so sharing a link cannot leak it. Even so, treat a production signing secret as you would a password and use a throwaway value for testing.
Why are only HS256, HS384 and HS512 supported?
They are symmetric, so a single shared secret both signs and verifies. RS, ES and PS are asymmetric and would require pasting a private key into a web form, which this tool deliberately avoids asking for.
What do iat and exp need to contain?
Both are NumericDate values measured in seconds since the Unix epoch, not milliseconds. Choosing an expiry here writes both correctly; supplying them in milliseconds is the most common way a hand-written token ends up rejected.
Can I add custom header fields?
The header is set to your chosen algorithm plus typ JWT. Custom members such as kid belong to a specific key management setup, so they are better added by whichever library issues your real tokens.
Should I use these tokens in production?
No. This is a tool for testing and debugging. Real tokens should be issued by your authentication service, which manages key rotation, revocation and claim validation.

Last updated:

Report a problem

Include the steps, expected result, and actual result. Remove secrets and personal data.

Related tools

Related articles