JWT Generator

Sign a JSON Web Token with HS256, HS384, or HS512 directly in your browser. Type your header and payload, pick an algorithm, supply a secret, and get the signed token — header, payload, and signature joined into the standard <code>xxx.yyy.zzz</code> shape. Signing uses the Web Crypto API, so nothing is ever sent to a server. Pair with the <a href="/jwt-decoder/">JWT decoder</a> to verify the output round-trips correctly.

JWT inputs

How to Use This Tool

  1. Edit the header and payload JSON — the header is pre-filled with the algorithm and type. Add or remove claims in the payload (sub, exp, iat, custom fields). Both must be valid JSON.
  2. Pick an algorithm — HS256 is the most common; HS384 and HS512 add larger signatures with no UX difference.
  3. Enter your secret — at least 32 bytes for HS256. Use a random value, not a password. The secret never leaves your browser.
  4. Click Generate — the signed JWT appears as header.payload.signature. Copy and use it in an Authorization: Bearer header or wherever you need.
  5. Verify the round-trip — paste the result into the JWT decoder to confirm the structure decodes cleanly and the claims match what you signed.

How JWT Signing Works

A JWT is built in three steps. First, the header is JSON describing the signing algorithm and the token type — typically {"alg":"HS256","typ":"JWT"}. Second, the payload is JSON containing claims like sub (subject — usually a user ID), iat (issued at, a Unix timestamp), exp (expiration, also a timestamp), and any custom fields your app needs. Third, the signature is computed over the base64url-encoded header and payload joined by a dot, using HMAC-SHA256 (for HS256) and the shared secret. All three parts are then base64url-encoded and joined with dots to produce the final header.payload.signature string.

Receivers verify a JWT by re-computing the signature from the received header and payload using the shared secret, then comparing it against the signature in the token. If the bytes match, the token wasn't tampered with after signing. If they don't, the token is rejected. This is why HMAC JWTs work for stateless auth: any service that holds the secret can verify any token without contacting a central server.

The most important security rule is to validate the alg field on the receiving side and refuse any algorithm you didn't expect. The infamous alg: none attack exploited servers that trusted the token's claimed algorithm; modern libraries hard-code which algorithms are acceptable. Also validate exp (reject expired tokens) and ideally iss (the issuer) and aud (the audience) before trusting any claims in the payload.

Frequently Asked Questions

What is a JSON Web Token?
A JSON Web Token (JWT) is a compact, URL-safe way to represent claims between two parties. It has three parts joined by dots: a base64url-encoded header (algorithm + token type), a base64url-encoded payload (the claims — user ID, expiration, custom data), and a signature computed from the header and payload using a secret or private key. The receiver verifies the signature to confirm the token wasn't tampered with. JWTs are heavily used for stateless authentication, API access tokens, password reset links, and OAuth 2.0 / OIDC flows.
What is the difference between HS256, HS384, and HS512?
All three are HMAC algorithms — symmetric, meaning the same secret signs and verifies. The number is the SHA-2 variant used: HS256 uses SHA-256 (32-byte output), HS384 uses SHA-384 (48-byte), HS512 uses SHA-512 (64-byte). HS256 is the most widely supported and is fine for most use cases. HS384 and HS512 produce larger signatures and add a small security margin against future cryptanalysis but are otherwise equivalent in practice. Use HS256 unless you have a specific reason; the security difference matters far less than choosing a strong secret.
How long should my JWT secret be?
At least as long as the hash output — 32 bytes for HS256, 48 bytes for HS384, 64 bytes for HS512. Shorter secrets reduce the effective key strength below the algorithm's design level and are vulnerable to brute-force search. For production, use a randomly generated secret from a cryptographically secure source (Node's crypto.randomBytes(32), Python's secrets.token_bytes(32), or the password generator with 32+ characters). Never use a human-typed password or a value short enough to fit in a config file comment.
Why does this tool only support HS256, HS384, and HS512?
HMAC variants are symmetric (one secret) and work entirely with browser-native Web Crypto APIs. RS256, ES256, and the other asymmetric algorithms require importing a PEM-encoded private key, which adds significant UX complexity for what is mostly testing and learning. For production token signing with RSA or ECDSA, do it on a server where the private key lives in a secrets store; for testing those algorithms, use jwt.io's debugger which has the key-import flow built in. The HMAC variants here cover the most common testing and debugging use cases.
Should I use this tool to generate production JWTs?
No. Generate production tokens server-side, in your application, with the secret stored in environment variables or a secrets manager. Browser-based token generation is appropriate for testing your token-handling code, debugging a JWT that's failing verification, generating sample tokens for documentation, or learning how JWTs work. Pasting a production secret into any browser tool is a bad habit even when the tool is provably client-side — there's no upside and the downside (typo, screenshot, screen share) is real.