KeyGenerator.io

JWT Secret Generator

HMAC signing secrets for HS256, HS384 and HS512, generated in your browser.

0 bits of entropy

Key size
Encoding

Press Space for a new secret, C to copy. Generated with crypto.getRandomValues on your own device.

How this secret is made

A token signed with HS256, HS384 or HS512 is verified with the same secret that signed it. That secret is not a password: nobody types it, nobody has to remember it, and it should never be readable or pronounceable. It is a block of random bytes that lives in an environment variable or a secret manager, and its only job is to be impossible to guess.

The bytes here come straight from crypto.getRandomValues, the browser's cryptographically secure random number generator, and are then written out as hexadecimal or Base64. Nothing in the path is seeded from a timestamp, a counter, or Math.random. Picking 256 bits gives you 32 random bytes, 384 gives 48, and 512 gives 64 — the output length matches the hash the algorithm uses.

The value is generated and kept in your browser. Reloading clears it.

Questions

How long should a JWT secret be?

At least as long as the hash output of the algorithm signing the token: 32 bytes (256 bits) for HS256, 48 bytes for HS384, 64 bytes for HS512. HMAC hashes any key longer than its block size back down, so a 200-byte secret is not meaningfully stronger than a 64-byte one. Going shorter is where the real risk sits.

Is hex or Base64 stronger?

Neither. They are the same random bytes written two ways — 32 bytes are 64 hex characters or roughly 44 Base64 characters, with identical strength. Choose whichever your library expects. If a config file or shell script is going to mangle the value, hex is the safer spelling because it contains nothing but 0-9 and a-f.

When do I need Base64URL instead of Base64?

Base64URL swaps the + and / characters for - and _ and drops the padding, so the value survives being put in a URL, a query string, or a filename without escaping. Standard Base64 is fine everywhere else. JWTs themselves are Base64URL-encoded, but that concerns the token, not the secret used to sign it.

Can I just use a password or a passphrase?

You can, but doing so makes HMAC signing vulnerable to offline guessing. A memorable phrase carries far less entropy than its length suggests, and an attacker holding a single valid token can test candidate secrets offline as fast as their hardware allows. Nothing rate-limits that. Use random bytes.

Where should the secret live?

In an environment variable, or a secret manager if you have one. Never in the repository — a secret committed to git stays in the history after you delete it, and history gets cloned, forked, and backed up. If one has been committed, rotating it is the only real fix.

How often should it be rotated?

On a schedule you actually keep, and immediately after any suspected exposure. The practical obstacle is that rotating invalidates every token signed with the old secret. Systems that need to rotate without logging everyone out usually accept two secrets during a window: sign with the new one, verify against both, then retire the old.

Does this work for RS256 or ES256?

No. Those are asymmetric: they sign with a private key and verify with a matching public key, so what you need is a key pair, not a shared secret. This page generates symmetric HMAC secrets, which is what the HS family uses. If your issuer and verifier are separate parties, the asymmetric algorithms are usually the right choice.