JWT Generator
Build and sign a JWT token. Set your payload claims, pick an algorithm, enter your secret, and generate a ready-to-use token.
The secret-encoding detail that breaks cross-tool verification
Whatever you type into the Secret field is signed as raw UTF-8 text — the bytes of the characters you typed, not a decoded representation of them. That matters specifically if you generate a secret with this site's own JWT Secret Generator, which outputs Base64URL, Base64, or hex — a text encoding of random bytes. Paste that output string in here and this tool hashes the literal characters of that string, not the underlying random bytes the string represents. The round trip on this site still works fine (generate here, sign here, decode here, all consistent), but if you need to verify that same token against a separate system that base64-decodes the secret into raw bytes before computing the HMAC — a common pattern in JWT libraries that accept a key file or base64 key parameter — the signatures won't match. Either configure the other system to treat the secret as plain text too, or generate your production secret as a plain random string rather than a base64-formatted one.
Algorithm guide
| Algorithm | Hash | Use when |
|---|---|---|
| HS256 | SHA-256 | Default choice — widely supported, fast |
| HS384 | SHA-384 | Need stronger hash, single-party system |
| HS512 | SHA-512 | Maximum HMAC strength |
| none | — | Testing only — never use in production |
Why the "none" algorithm exists here at all
Selecting none produces a token that's deliberately incomplete: header.payload. with a trailing dot and an empty signature segment. That's not a missing feature — it's exactly what an unsecured JWT looks like per the spec, and it exists here on purpose, for testing how your own code handles that shape of token. The historically real alg:none vulnerability worked by an attacker stripping a token's signature and changing the header's alg to none, hoping a careless verifier would trust the unsigned payload anyway. Generating one here on demand is a quick way to confirm your own ASP.NET Core JWT bearer configuration actually rejects it, rather than assuming the default validation settings do.
The other thing worth noting about the signing itself: this tool re-serializes your payload JSON before encoding it, rather than embedding your exact input text byte-for-byte. Paste in JSON with extra whitespace or indentation, and what actually gets base64url-encoded into the token is the normalized, compact re-serialized version — same values, same key order, different surrounding bytes. That's invisible for almost every practical purpose, since any spec-compliant JWT consumer decodes and re-parses the payload as JSON rather than comparing raw bytes. It would only matter if you were trying to reproduce an exact byte-for-byte token from another system for a hash comparison rather than just generating a working token of your own.
How to use this tool
- Select an algorithm — HS256 is the most widely supported.
- Edit the payload claims. Set
expto control expiry (Unix timestamp). - Enter your secret key. Use the JWT Secret Generator to create a secure one. Keep it private — anyone with the secret can forge tokens.
- Click Generate and copy the token.
- Use the JWT Decoder on this site to inspect the header and payload.
Payload (JSON)
{
"sub": "1234567890",
"name": "John Doe",
"iat": 1784421223,
"exp": 1784424823
}Generated JWT
JWT token