Command Palette

Search for a command to run...

How JWT Signing Works: HS256 vs HS384 vs HS512

How JWT Signing Works: HS256 vs HS384 vs HS512

T
Toolz Team
|Sep 13, 2026|15 min lesen

Teil der Sammlung Sicherheit

JWT-Generator

Generieren und signieren Sie JSON Web Tokens mit HS256, HS384 oder HS512, fügen Sie Standardansprüche hinzu und kopieren Sie das Token. Läuft clientseitig.

JWT-Generator verwenden

The first time I had to debug a broken auth flow on a Laravel API, I wasted an afternoon because I could not produce a token I trusted. The middleware kept returning 401, and I could not tell whether the bug was in my verification code or in the token I was feeding it. I needed a known-good JWT with a specific sub, a specific expiry, and a secret I controlled, so I could isolate one side of the problem. Copying a random token off a Stack Overflow answer did the opposite of help, because it was signed with a secret I did not have.

That is the gap a JWT generator fills. It is not a production signing service. It is a bench tool for the moment you are building or testing something that consumes JSON Web Tokens and you need a valid one on demand, with the exact claims and the exact secret you choose. This guide covers how the tool works, how a JWT is assembled and signed, and the practical cases where generating a token by hand saves you real time.

TL;DR: A JWT generator turns a JSON payload plus a secret into a signed token. Paste your claims, pick HS256, HS384, or HS512, enter the secret, and copy the token. The JWT Generator signs with the browser Web Crypto API, so the payload and secret never leave your machine. Use it to create test tokens with a known sub, a set expiry, or a deliberately expired exp to exercise your API's error paths. To read a token back, pair it with the JWT Decoder.

What is a JWT and what does the generator produce?

A JSON Web Token is a compact, URL-safe way to represent a set of claims. The structure is defined by RFC 7519, and the signed form, which is what almost everyone means by "a JWT," is a JSON Web Signature as defined by RFC 7515. A signed token has three parts joined by dots: header.payload.signature.

The header is a small JSON object naming the signing algorithm and the token type, something like { "alg": "HS256", "typ": "JWT" }. The payload is a JSON object of claims: who the token is about, when it expires, and whatever custom fields your application adds. Both the header and the payload are Base64url-encoded, which is ordinary base64 with two character substitutions and no padding, exactly as RFC 7515 specifies. The signature is a keyed hash computed over the first two parts.

The generator assembles all three. You supply the payload and the secret, it builds the header, encodes both segments, computes the signature, and joins them. The output is a string you can drop straight into an Authorization: Bearer header, a test fixture, or a curl command.

One thing worth being blunt about up front: a signed JWT is encoded, not encrypted. Anyone who holds the token can Base64url-decode the payload and read every claim in it. The signature does not hide the contents. It only proves the contents were not changed by someone without the key. Never put a password, an API key, or anything else you would not show the user inside a JWT payload.

How does the signing work?

For the HMAC family, which is what this tool signs with, the signature is HMAC(secret, header + "." + payload). HMAC is a keyed hash construction defined by RFC 2104, and the JWA specification, RFC 7518, maps the three JWT algorithm names onto it: HS256 uses HMAC with SHA-256, HS384 uses SHA-384, and HS512 uses SHA-512.

The important property is symmetry. The same secret both creates and verifies the signature. When your server receives a token, it recomputes HMAC(secret, header + "." + payload) over the received first two segments and checks that the result equals the signature segment. If a single byte of the payload was altered, the recomputed hash will not match and verification fails. That is the entire integrity guarantee.

Because it is symmetric, the secret is the whole game. Anyone with the secret can mint valid tokens for your system, which is why the generator runs the signing in your browser through the Web Crypto API and never transmits the secret anywhere. You can confirm this by opening your browser's Network tab while you generate a token: there is no request. This matters more than it sounds, because pasting a live production signing secret into a random web tool that phones home would be handing over the keys to your authentication.

RS256 and ES256, the asymmetric algorithms, work differently: a private key signs and a matching public key verifies. Those are the right choice when many services need to verify tokens but only one should be able to issue them. This tool deliberately does not offer them, because signing with them means pasting a private key into a web page, and that is a habit worth never starting.

How to use the JWT Generator

Step 1: Write the payload

Enter your claims as a JSON object. A minimal example is { "sub": "1234567890", "role": "admin" }. The sub claim is the subject, usually a user id. You can add any custom fields your application reads, such as role, scope, tenant_id, or email. The tool keeps whatever you put here exactly as written.

Step 2: Add the time claims

Leave issued-at on and the tool stamps iat with the current Unix time. Set an expiry in seconds to add an exp claim computed as now plus that offset. For a fifteen-minute access token, enter 900. For a one-hour token, enter 3600. These are the claims most authentication bugs come down to, so having them computed correctly, in seconds since the epoch rather than milliseconds, removes a common mistake.

Step 3: Choose the algorithm and secret

Pick HS256 unless you have a reason to use HS384 or HS512. Enter the signing secret in the field. Then choose how the secret is interpreted: plain text uses the UTF-8 bytes of what you type, while base64url and hex decode the string first into raw bytes. This choice matters because many systems store the secret already base64-encoded, and if you feed the encoded string as plain text you will produce a signature that does not match.

Step 4: Copy the token

The signed JWT appears along with a decoded preview of the header and payload so you can confirm every claim before using it. Copy it and paste it wherever you need it.

Why generate a token by hand?

Testing your API's happy path

When you write middleware that validates JWTs, you need a token your code should accept. Generate one signed with the same secret your verifier uses, with a valid exp, and confirm the request returns 200. If it does not, the bug is in your verification logic, not the token. This single isolation step is why I reach for the tool most often.

Testing the failure paths

A robust API rejects the right tokens for the right reasons. Generate a token with an exp already in the past to confirm you return the correct expired-token error. Generate one with a nbf in the future to test the not-yet-valid path. Generate one signed with the wrong secret to confirm your signature check runs. These negative cases are the ones that get shipped untested, and a generator makes them a thirty-second job.

Reproducing a bug from a specific user

Support reports a problem that only happens for accounts with a particular role. Generate a token with that exact role claim and the affected user's sub, and you can reproduce the request locally without touching production data or asking the user for their real bearer token, which you should never do anyway.

Seeding local development

New developers on a team need a working token to hit protected endpoints while the front end auth is still being built. A generated token signed with the local development secret unblocks them immediately.

HS256 vs HS384 vs HS512: which should you use?

Algorithm Hash Signature size Minimum key length When to use
HS256 SHA-256 32 bytes 32 bytes The default. Fast, widely supported, secure for almost all uses
HS384 SHA-384 48 bytes 48 bytes When a policy or standard requires SHA-384
HS512 SHA-512 64 bytes 64 bytes High-security contexts, or when you already standardize on SHA-512

The practical answer is HS256 unless something external requires otherwise. RFC 7518 requires the key to be at least as long as the hash output, so 32 bytes for HS256, 48 for HS384, and 64 for HS512. The generator warns when your decoded secret is shorter than the minimum, because a short key weakens the signature regardless of the algorithm name. A longer, higher-numbered algorithm does not fix a weak secret; a proper-length random secret is what matters.

Common mistakes and how to avoid them

The most frequent one is a secret mismatch caused by encoding. Your framework stores the secret as base64, you paste the base64 string as plain text, and now the key bytes differ from what your verifier uses. The signatures never match and you chase a phantom bug. Fix it by choosing the correct secret encoding in the tool so the raw key bytes are identical on both sides.

The second is confusing seconds and milliseconds. The registered time claims in RFC 7519 are all measured in seconds since the Unix epoch. JavaScript's Date.now() returns milliseconds. If you compute exp yourself and forget to divide by 1000, your token appears to expire fifty thousand years from now, which some strict verifiers will reject. Letting the generator compute the claims avoids this entirely.

The third is treating the payload as private. It is not. If you are tempted to store a secret in a claim, stop. Anyone with the token can read it. Store only what you are comfortable with the token holder seeing, and keep genuinely secret data on the server.

Where JWTs fit alongside other tools

Once you have generated a token, the natural next step is to read it back. The JWT Decoder splits any token into its header and payload and flags an expired exp, which is how you confirm the generator produced what you intended. If you are also generating secrets, the Hash Generator computes SHA hashes client-side, and the Password Generator produces the kind of long random string that makes a good HMAC secret in the first place. If you want to understand the Base64url step by hand, the Base64 Encoder / Decoder shows the same reversible transform that turns the header and payload into their encoded form. And when you need a random identifier to drop into a sub or jti claim, the UUID Generator gives you one in the right format.

For the broader picture of why browser-based tools keep sensitive material off third-party servers, the data privacy in online tools guide explains the client-side model, and the web developer toolkit rounds up the utilities that pair well with token work.

How does a server verify the token you generate?

It helps to know what happens on the other side, because it explains why the secret and the claims have to be exactly right. When your API receives a token, a library like jsonwebtoken, jose, or PyJWT does three things in order. It splits the token on the dots and Base64url-decodes the header to read the alg. It recomputes the signature over header.payload using the configured secret and compares it, byte for byte, against the signature segment. And it checks the registered claims: is exp in the past, is nbf in the future, does iss and aud match what the API expects.

Every one of those checks maps to something the generator lets you control. If verification fails on the signature, the secret or its encoding differs between the two sides. If it fails on exp, the token has expired, which you may have caused on purpose to test that path. If it fails on alg, you generated a token with an algorithm the verifier is not configured to accept, which is itself a useful thing to discover. Generating tokens with deliberate variations is how you map out exactly which check your API enforces and which it silently skips.

A word on the alg header specifically. RFC 7515 defines none as a valid algorithm for an unsigned token, and early libraries would trust a token that claimed alg: none and skip verification entirely. That is the classic JWT vulnerability. Modern libraries reject it by default, but the generator offers the none option precisely so you can fire an unsigned token at your API and confirm it says no. If your API ever accepts one, you have found a serious bug.

How should you handle secrets and token storage?

The secret you sign with deserves the same care as a database password. A good HMAC secret is a long, random string, not a memorable phrase, because HMAC security depends on the key being unguessable. Generating one with a password tool and storing it in your environment configuration, never in source control, is the baseline. When you rotate it, remember that every token signed with the old secret becomes invalid the moment the verifier switches, which is why production systems usually support more than one valid secret during a rotation window.

On the client side, where you store the finished token matters as much as how you sign it. A token in localStorage is readable by any JavaScript on the page, so a single cross-site scripting flaw hands an attacker a valid credential. An httpOnly, Secure, SameSite cookie is invisible to scripts, which closes that path at the cost of needing CSRF protection. The common pattern is a short-lived access token kept in memory and a longer-lived refresh token in an httpOnly cookie. None of this changes how you generate a token, but it is the context that makes a generated token safe to use rather than a liability.

FAQ

How do I generate a JWT?

Paste your claims as a JSON object, pick a signing algorithm such as HS256, and enter the secret. The tool base64url-encodes the header and payload, computes the HMAC signature, and returns the finished token for you to copy. Everything runs in your browser.

Which signing algorithms are supported?

HS256, HS384, and HS512, the HMAC family, plus an unsigned "none" option for testing. RS256 and ES256 are deliberately not offered because they sign with a private key, and pasting a private key into a web page is a security risk best avoided.

Is my secret sent to a server?

No. The signing runs entirely in your browser through the Web Crypto API, so the secret and the payload never leave your device. You can confirm this in the DevTools Network tab, and the tool keeps working offline once loaded.

How do I set the token to expire?

Enter an expiry in seconds and the tool adds an exp claim equal to the current time plus that many seconds. For a fifteen-minute token enter 900. Leave the field empty to omit exp entirely.

Why should the secret be at least 32 bytes?

RFC 7518 requires an HMAC key at least as long as the hash output, which is 32 bytes for HS256, 48 for HS384, and 64 for HS512. A shorter secret weakens the signature, so the tool warns when the decoded secret is too short.

Can I create an unsigned token?

Yes. Select alg none and the tool produces a header.payload. token with an empty signature. This is only for testing how your API handles unsigned tokens; most libraries reject alg:none by default, and you should too.

Is a generated JWT encrypted?

No. A signed JWT is encoded, not encrypted: anyone can base64url-decode the header and payload and read every claim. The signature only proves the contents were not changed. Never put passwords or secrets inside the payload.


Comments

0 comments

0/2000 characters

No comments yet. Be the first to share your thoughts!