How long should a JWT secret be?
The short answer: 32 bytes for HS256, 64 for HS512. The longer answer is worth two minutes.
A full-entropy signing secret
The short answer
HS256: at least 256 bits — 32 random bytes. HS512: at least 512 bits — 64 random bytes. This is not a rule of thumb, it is a requirement: RFC 7518 §3.2 states that a key for HMAC-SHA-256 must be at least the size of the hash output, and the same clause applies to HS384 and HS512. The generator above emits exactly that.
Why "length" is the wrong word
The requirement is about entropy, and that is why so many people satisfy the character count and remain vulnerable. correct-horse-battery-staple-2024! is 33 characters, so it clears "32 characters" — and it carries maybe 60 bits of real entropy, because it is words a human chose. A brute-forcer does not enumerate 256-bit keyspaces; it enumerates the space your secret was actually drawn from. Random bytes have no smaller space to fall back to. This is why the answer is always "32 random bytes" and never "a long passphrase".
What a weak secret actually costs
An attacker needs one thing: a single token signed by you, which they get by signing up. That token contains its own signature, so they can test candidate secrets offline, on their own GPU, at millions of guesses per second, with nothing hitting your servers. When they find it, they mint tokens with any claims they like — "role": "admin", any user id — and your API verifies them correctly, because they are correctly signed. Nothing in your logs looks unusual. Tools that do this against JWTs are a standard part of the offensive toolkit; this is a routine finding, not a theoretical one.
IDX10603 and friends
If you landed here from IDX10603: The algorithm: 'HS256' requires the SecurityKey.KeySize to be greater than '128' bits, that .NET error means exactly what this page is about: your signing key is too short. The fix is a key of at least 32 bytes — copy the HS256 value above into your configuration. One subtlety: .NET measures the UTF-8 byte length of the string you supply, so a 20-character password fails the check even if it looks complicated, and padding it to 32 characters of human-chosen text passes the check while leaving the real weakness in place.
When HS-anything is the wrong choice
HMAC secrets are symmetric: whoever can verify a token can also forge one. That is fine for a single service that both issues and checks its own tokens. The moment a second service needs to verify, you are handing out your signing key — and it only takes one of those services to leak it. At that point switch to RS256 or EdDSA, where verifiers hold only a public key and cannot sign. Picking HS512 over HS256 does not help with this at all: HS256 with a full-entropy random key is not a practical weak point, so choose HS512 for policy or stack consistency, not for safety.
How long should a JWT secret be?
At least 256 bits — 32 random bytes — for HS256, and 512 bits (64 bytes) for HS512. RFC 7518 §3.2 requires a key at least the size of the hash output. The important word is random: a 40-character phrase you invented clears the character count and still has only about 60 bits of real entropy.
Can I just use a long passphrase?
No. Brute-forcers do not enumerate the 256-bit keyspace, they enumerate the space your secret was actually drawn from. A human-chosen phrase — however long — comes from a space small enough to search. Random bytes have no smaller space to fall back to.
How would anyone even attack a weak JWT secret?
They sign up, get one token, and crack it offline on their own GPU — the token carries its own signature, so nothing touches your servers while they guess. Once they have the secret they mint tokens with any claims they like, and your API verifies them correctly because they are correctly signed. Your logs show nothing unusual.
HS256, HS512, or RS256?
HS256 with a full-entropy random key is not a practical weak point, so HS512 is a policy or stack-consistency choice, not a security upgrade. The decision that actually matters is symmetric versus asymmetric: if more than one service verifies your tokens, use RS256 or EdDSA so verifiers hold only a public key and cannot forge.
Nothing leaves your browser
- Don't take our word for it — turn off your wifi. Every generator on this site keeps working with the network disconnected. That's the whole proof, and it takes five seconds.
- Every value comes from
crypto.getRandomValues()— the CSPRNG built into your browser, neverMath.random(). - Generated secrets are never transmitted, logged or stored: no server-side generation, no cookies, no localStorage.
- Verify it yourself in the network tab: after loading, the page only talks to our self-hosted, cookie-less analytics — which counts page views and which generator type gets copied, never any value.
- Strict Content-Security-Policy; no third-party script origins.