Skip to content

JWT Generator: Create and Sign a JWT Token Online with Custom Claims

Free JWT generator — sign tokens with HS256/384/512 and custom claims, generate a throwaway secret, and test expired or malformed tokens safely.

Try it now: JWT Generator Sign a JWT with HS256, HS384 or HS512 and custom claims, generate a strong signing secret, and see which claims a validator will object to.

Why You'd Generate a JWT Instead of Just Decoding One

Most of the time a JWT shows up because something else issued it — an auth server, a login endpoint, a third-party API. But there are a handful of situations where you need to produce one yourself. You're testing an API endpoint locally that expects a valid Authorization: Bearerheader, and standing up a real identity provider just to get a token is overkill for a five-minute check. You're debugging an edge case — how does the middleware behave when exp is five seconds in the past, or when auddoesn't match — and reproducing that with a real login flow means fighting the clock or the config instead of just setting the claim. Or you need a throwaway signing secret for a local dev environment and don't want to reuse anything that touches a real system. A JWT token generator exists for exactly this: crafting a specific, deliberate token on demand, claims and all, without a login round trip in the way.

HS256, HS384, HS512 — and Why This Tool Stops There

The three algorithms a JWT generator like this one offers — HS256, HS384, and HS512 — are all HMAC variants: symmetric signing, where the same secret both signs and verifies the token. The number is the underlying SHA hash size (256, 384, or 512 bits), which affects the signature's length and collision resistance, not how you use it. You pick one, supply a secret, and the same secret has to be configured on whatever verifies the token later. That's the entire trust model: possession of the secret is possession of the ability to both sign and verify.

That's deliberately different from RS256 or ES256, the asymmetric algorithms where a private key signs and a separate public key verifies — the pair a real production identity provider typically uses so that services validating tokens never need the signing key at all. This generator doesn't attempt to replace that. Asymmetric signing needs a real key pair with real key management, and faking one for a test token buys you nothing beyond what HMAC already covers for local testing. If your actual system signs with RS256, testing the shape of a token — its claims, its expiry, its structure — with an HS256 stand-in is almost always sufficient, because what you're usually verifying is your own code's handling of the claims, not the cryptography itself.

A Signing Secret Is Not Something to Paste Into a Browser Tool

One thing worth being direct about: this is a testing and development tool, and it should only ever see testing and development secrets. Never paste a real production signing secret into any browser-based tool — including this one, even though it runs entirely client-side and computes the signature locally without sending anything to a server. The risk isn't where the HMAC computation happens; it's the act of pasting a production secret into a text field at all. Clipboard history, browser extensions, a shoulder-surfed screen, a copy-paste into the wrong window — the exposure surface has nothing to do with client-side versus server-side execution. A secret typed into any tool outside your production secret manager should be treated as burned.

The fix is simple: use a jwt secret key generator to generate a fresh, random, throwaway secret for local testing, and never let a real one anywhere near it. GenKitLab's tool includes exactly that — a button that generates a strong random secret alongside the claims editor, so there's no reason to reach for a production value even out of convenience.

Claims Worth Setting on Purpose

The default temptation when you create a JWT for testing is to fill in a plausible-looking payload and move on. That's fine for a happy-path check, but the more useful exercise is setting claims deliberately to probe how your code handles the cases that don't work:

  • An exp in the past. Set the expiry to a timestamp before now and confirm your middleware actually rejects it with the error you expect, rather than silently accepting an expired token because the check was never wired up.
  • An exp a few seconds from now. Useful for testing near-expiry behavior — token refresh logic, grace-period handling, or a race condition between a request being issued and the token expiring mid-flight.
  • An aud or iss that deliberately doesn't match. If your validator checks audience and issuer, a token signed correctly but scoped to the wrong audience should still be rejected — this is the easiest way to confirm that check actually runs instead of assuming it does because the code looks like it should.
  • A missing required claim. Drop sub or whatever custom claim your application depends on and see what error message comes back. A validator that fails with a clear, specific error is doing its job; one that throws a generic 500 or — worse — proceeds withundefined is a bug you just found for free.

Here's a claims payload with several of those set at once, and the HS256 token it produces:

claims in
{
  "sub": "usr_8f2b",
  "role": "admin",
  "aud": "internal-api",
  "iss": "genkitlab-test",
  "iat": 1753900800,
  "exp": 1753900860
}
signed JWT out (HS256)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3JfOGYyYiIsInJvbGUiOiJhZG1pbiIsImF1ZCI6ImludGVybmFsLWFwaSIsImlzcyI6ImdlbmtpdGxhYi10ZXN0IiwiaWF0IjoxNzUzOTAwODAwLCJleHAiOjE3NTM5MDA4NjB9.4kR0v2WQyq1p8s5LZfN3JmO7cX0iH1tYdE6nB9AaGpU

That exp is exactly sixty seconds after iat— deliberately short, so you can watch the token expire in real time while testing rather than waiting on a default hour-long lifetime. That's the kind of value worth setting on purpose rather than leaving at whatever a template suggests.

Sign It, Then Decode It Back

A generator and a decoder are two ends of the same operation, and using them together is the fastest way to confirm a token is actually correct before you hand it to whatever you're testing. Sign a token here, paste the result into JWT Decoder, and check that the header, claims, and expiry read back exactly as you set them — the full breakdown of how a JWT's three parts fit together is covered in the JWT Decoder guide. GenKitLab's JWT Generator runs entirely in your browser — the claims you enter and the secret you use to sign JWT tokens never leave the page, nothing is uploaded, and closing the tab leaves no trace of either.

Frequently asked questions

What is a JWT token generator for?

It signs a JSON payload of claims into a valid JWT without needing a real auth server — useful for testing an API endpoint locally, crafting a token with a specific expired or malformed claim to check error handling, or generating a throwaway token for local development.

Which algorithm should I use — HS256, HS384, or HS512?

For testing purposes it rarely matters — all three are HMAC (symmetric) algorithms where the same secret signs and verifies, differing only in the underlying hash size. Match whichever one your actual system uses in production so the token shape is representative; HS256 is the most common default.

Can this generator create RS256 or ES256 tokens?

No — it covers HS256, HS384, and HS512 only, all symmetric HMAC signing. RS256 and ES256 are asymmetric algorithms that need a real private/public key pair with real key management, which isn't something worth faking for a test token. For most testing, an HS256 stand-in is sufficient to exercise your claim-handling logic.

Is it safe to generate a JWT with a real production secret in a browser tool?

No. Never paste a real production signing secret into any browser-based tool, even one that computes entirely client-side. The risk is the act of pasting a secret outside your production secret manager, not where the computation happens. Generate a fresh, random throwaway secret for local testing instead.

What claims should I set when testing token expiry?

Set exp to a timestamp in the past to confirm expired tokens are actually rejected, or a few seconds in the future to test near-expiry and refresh behavior. Also worth testing deliberately: an aud or iss that doesn't match what your validator expects, and a required claim left out entirely to see what error message comes back.

Does the JWT generator send my claims or secret to a server?

No. Signing happens entirely in your browser using the Web Crypto API — the claims and secret you enter never leave the page, and nothing is uploaded or logged.

Last updated