What the JWT Generator Does
The JWT Generator mints JSON Web Tokens signed with HMAC-SHA256 (HS256), entirely in the browser. Paste the payload as JSON into the input panel, set the Secret field in the options bar, and run the transform. The output is a standard three-segment token — header.payload.signature — that you can copy straight into an Authorization: Bearer header, a cookie, or a test fixture.
Two algorithm choices are offered in the selector: HS256 and none. With HS256 the tool computes a real HMAC-SHA256 signature over the encoded header and payload using your secret, via the browser's Web Crypto API — the signature is cryptographically genuine and verifiable by any JWT library. With none the tool emits the unsigned form: the header says alg:none and the token ends in a bare dot with no signature. The header is always {"alg":"HS256","typ":"JWT"} (or alg:none), and the payload is exactly the JSON you supply — the tool adds no claims of its own.
If the input panel is empty the tool generates a token with an empty payload. Payload text that is not valid JSON is rejected with an explicit error — the tool will not guess at malformed claims, because a token with subtly broken JSON is worse than no token at all.
How the JWT Generator Works
A JWT is three Base64Url-encoded strings joined by dots. Base64Url is standard Base64 with + swapped for -, / for _, and padding stripped, so the token passes through headers and URLs unescaped. The tool builds each part in sequence:
header = b64url({alg: "HS256", typ: "JWT"})
payload = b64url(JSON.parse(input))
signature = b64url(HMAC-SHA256(header + "." + payload, secret))
The signature step is the only cryptographic part, and it is a real one. The tool imports your secret as a raw HMAC key in Web Crypto, signs the exact bytes header.payload, and Base64Url-encodes the 32-byte result. Any conforming library — jwt.io libraries in Node, Python, Java, Go — verifies that signature identically. The signing happens locally: the secret and the token never leave the page.
HS256 is a
symmetric scheme: the same secret both signs and verifies. That is why this tool pairs naturally with the
JWT HS256 Verifier — generate a token with a secret here, verify it with the same secret there, and the round trip demonstrates exactly what your auth server does. The symmetry is also HS256's structural limitation: every service that can verify tokens holds the signing power too, which is why distributed systems move to RS256 (asymmetric) instead.
The none algorithm exists in the standard for completeness and appears in the tool for realism: some specs and test suites require constructing unsigned tokens. A token with alg:none carries no proof of origin whatsoever — anyone can create one with any claims. Production servers must reject such tokens, and libraries do by default; the option is here so you can see the shape and test how systems respond to it, not so you can smuggle claims past a properly configured server.
Using the JWT Generator
- Step 1 — Write the payload JSON. In the input panel, enter the claims as a JSON object, e.g.
{"sub":"user-1042","role":"admin","exp":1798761600}. Standard registered claims (sub, iss, exp, iat, nbf, aud) and custom claims are all passed through verbatim — the tool does not validate their semantics. - Step 2 — Choose the algorithm. The options bar offers
HS256 (signed) and none (unsigned). Use HS256 unless you specifically need to observe unsigned-token behaviour. - Step 3 — Set the secret. Type any string into the
Secret field. The same secret will be required to verify the token later; with none selected the secret is unused. - Step 4 — Run and copy the token. The output panel shows the three-segment token. Copy it with the copy button and use it wherever the receiving system expects a bearer token.
- Step 5 — Verify the round trip. Paste the generated token into the JWT HS256 Verifier with the same secret — it should report the signature valid. Then change one payload character and verify again: the signature no longer matches. That contrast is the whole security model in two runs.
Common Use Cases
Test fixtures for API development. When building or testing an endpoint that expects a bearer token, generate tokens with precisely the claims your test needs — a specific role, tenant, or expiry — without spinning up your full auth service. Expired tokens, wrong-issuer tokens, and tokens with missing claims are all one payload edit away, which makes negative-path testing cheap.
Learning how signatures actually behave. Generate a token, then flip one character in the payload segment and run it through the verifier. The signature check fails even though the token still parses. Doing this once makes the tamper-evidence property concrete in a way no description matches.
Debugging claim-based authorisation. If a gateway filters on a claim, generate tokens with and without it and compare behaviour. Because the payload is fully under your control here, you can isolate exactly which claim drives the decision.
Reproducing tokens from logs. When an incident report includes a token, regenerating a token with the same payload (not the same signature — you lack the secret) lets you diff claims against what your service expected to receive.
Illustrating the alg:none danger. Generate an unsigned token with inflated claims and hand it to a staging service. If the service accepts it, the staging configuration is skipping signature verification — a finding worth fixing before it ships.
Worked Example
Enter this payload, leave the algorithm at HS256, and keep the default secret secret:
{ "sub": "user-1042", "role": "admin", "exp": 1798761600 }
The tool emits:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTEwNDIiLCJyb2xlIjoiYWRtaW4iLCJleHAiOjE3OTg3NjE2MDB9.UNpi4iFoyJ5E5CiApSI3t8_E0QFlBLDw7dyDDxjY1WI
Decoding the pieces: the header is
{"alg":"HS256","typ":"JWT"}; the payload is exactly the claims entered; the signature is 43 Base64Url characters — 32 raw bytes of HMAC output. The
exp value 1798761600 is epoch seconds for 2027-01-01T00:00:00Z, so the token is valid until then. Pasting this token into the
JWT Decoder reproduces the header and payload, and the
JWT Expiry Checker reports the time remaining.
Change the secret to secret2 and regenerate: only the signature segment changes, because the signed bytes are identical. That is HS256 in one observation — same claims, different key, completely different proof.
Tips and Common Mistakes
- The secret is the entire security model. HS256 verification succeeds only with the identical secret string. Use long random secrets for anything real — a dictionary word is brute-forceable from a single token, and tools like the Token Strength Analyzer show why short secrets are weak.
- Tokens generated here are for testing. The page keeps no keys and issues nothing revocable. Never treat a browser-generated token as production identity; mint those from your auth server where the secret stays server-side.
exp is in epoch seconds. 1798761600 is January 2027; the same value interpreted as milliseconds would be January 1970. Libraries disagree on tolerance — write seconds, as the JWT standard requires.- The tool does not add
iat or exp for you. If your test needs them, include them in the payload JSON yourself. This is deliberate — fixtures should be byte-predictable, not quietly mutated. - Payload whitespace does not survive. The payload is re-serialised from parsed JSON, so key order and indentation may differ from your input — what matters is the data, and the signature is computed over the re-serialised form. Two tokens with the same claims but different key order have different signatures and different payloads.
- Do not confuse this with the verifier. This tool signs with a secret you hold. The JWT HS256 Verifier checks an existing token against a secret. They are the two halves of symmetric JWT auth.
Frequently Asked Questions
Are the generated signatures real?
Yes — with HS256 selected, the signature is a genuine HMAC-SHA256 computed in Web Crypto over the encoded header and payload with your secret. Any standards-conforming JWT library verifies it. The only non-real aspect is provenance: the token was minted in a browser, not by your auth server, so treat it as a test artefact rather than an identity.Can I generate RS256 or ES256 tokens?
No — the tool offers HS256 and none. RS256 requires an RSA private key of the kind the
RSA Key Generator produces, and signing with it belongs in your key-management setup rather than a browser test page. For most testing purposes an HS256 token exercises the same code paths: parse, verify claims, check expiry.
Why does my token end with a dot?
A trailing dot means the signature segment is empty — the token was generated with alg:none. That is the standard's unsigned form: two readable segments and no proof. It is useful for observing how systems handle unauthenticated tokens, and production servers should reject it.Is the secret sent anywhere?
No. Key import, signing, and Base64Url encoding all happen in the page via the browser's Web Crypto API. No network request carries the secret or the token; closing the tab discards both. The same reasoning that makes this safe here applies to any tool — never paste a production signing key anywhere you cannot verify runs locally.Why won't my payload with a trailing comma parse?
The payload must be strict JSON — no trailing commas, no comments, unquoted keys, or single quotes. The tool rejects malformed JSON rather than repairing it, because a JWT's payload is consumed by machines. If you need to fix broken JSON first, the
JSON Repair Tool handles that, and you can paste the repaired object here.
Related Tools