JWT generator — sign HS256, HS384 or HS512 test tokens in your browser

Paste a JSON header and payload, enter a shared secret, and get a signed JSON Web Token using HS256, HS384 or HS512, signed in your browser with the Web Crypto API and identical to what jwt.io produces for the same inputs.

Live demo · real result from this tool

Press Generate to create a result.

Processed on your device — nothing is uploaded.

How to use the JWT generator

  1. Enter the Header (JSON). The default is {"alg":"HS256","typ":"JWT"}. It must be a JSON object.
  2. Enter the Payload (JSON) with your claims, for example sub, iat and exp.
  3. Type the Secret, and set Secret encoding to Text (UTF-8), Base64 / Base64URL or Hex, to match how your server reads it.
  4. Pick the Algorithm: HS256, HS384 or HS512.
  5. Copy the Signed JWT. It updates as you type, and any JSON error is shown with its line and column.

What it does and when to use it

Use it to make tokens for local development and API tests. For example, call an endpoint that expects a Bearer token, or reproduce a bug with specific claims, without writing a signing script first.

To read or verify an existing token, paste it into the JWT debugger. For other HMAC signatures, such as webhook bodies, use the HMAC generator. The Base64URL encoder shows the encoding that each part of the token uses.

How it works

This follows the JWS compact format from RFC 7515, with the HMAC algorithms defined in RFC 7518:

  1. The header is parsed, alg is set to your choice, and both header and payload are re-serialised with JSON.stringify. That makes them compact, with key order kept.
  2. Each part is UTF-8 encoded and then Base64URL encoded (no padding), and the two parts are joined with a dot.
  3. That string is signed with HMAC-SHA-256, -384 or -512 using the Web Crypto API, and the signature is Base64URL encoded and appended.

A secret shorter than the hash size (32, 48 or 64 bytes) triggers a warning, but the token is still produced.

Worked examples

All defaults, with secret your-256-bit-secret, reproduce the well-known jwt.io sample:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

The secret is only 19 bytes, so the warning appears: The secret is shorter than 256 bits.

A header that says "alg":"none" plus a kid, the payload {"sub":"42","exp":1767225600} and a 48-byte secret. The header’s alg is replaced with HS256 and no warning is shown:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImsxIn0.eyJzdWIiOiI0MiIsImV4cCI6MTc2NzIyNTYwMH0.ChB_N13Zfg_Tn9ais0f_wfXi6VvXd6GieKkBQWHV8L0

Limits and tips

  • The payload must be a JSON object. RFC 7519 requires the claims set to be an object, so a bare string, number or array is refused with an error.
  • A JWT is signed, not encrypted. Anyone with the token can read the payload, so never put passwords or personal data in it.
  • Formatting changes the bytes. Because the JSON is re-serialised, a token signed elsewhere from pretty-printed JSON can differ, even with the same claims.

Frequently asked questions

Can I sign RS256 or ES256 tokens here?
No. This tool only does HMAC algorithms (HS256, HS384, HS512), which use one shared secret. RS256 and ES256 need a private key and are not supported.
Why is the alg in my header changed?
The tool always sets alg to the algorithm you pick in the menu, so the header cannot claim one algorithm while the signature uses another. Other header fields, such as typ and kid, are kept as you wrote them.
Does it check exp, iat or other claims?
No. The payload is signed exactly as given. Nothing checks that exp is in the future, that times are in seconds rather than milliseconds, or that required claims are present. Use the unix timestamp converter to work out exp values.
Is it safe to paste a real production secret?
The secret is not sent anywhere, but anything pasted into a web page can be seen by browser extensions. Use test secrets here, and rotate any production secret you have pasted into a website.
My token does not verify in my backend. What should I check?
Check the secret encoding first. If your server decodes a Base64 secret, choose Base64 / Base64URL here; a text secret and its Base64 form give different signatures. Then check the algorithm and look for stray spaces.

Written by the ToolsRift team · Last updated

Pages are drafted with AI assistance and checked by automated tests. How we write and check pages.

Was this tool useful?

Report a problem

Start typing to search every tool.

↑ ↓ to moveEnter to openEsc to close