Skip to content

🪪 JWT Generator & Signer

Enter header, payload, and secret to produce a signed JWT entirely in your browser. Supports HS256 / HS384 / HS512 via Web Crypto API.

100% Free No signup Browser-only 5 languages Dark mode
Header (Base64URL)
Payload (Base64URL)
Signature (Base64URL)

⚠️ Security Notes

• Secrets are processed entirely in your browser using Web Crypto API and are never sent to a server.

• Entering production secrets into web tools is generally not recommended. Use for testing, learning, and debugging.

• HS256 secrets should be at least 256 bits (32 bytes); HS512 should be at least 512 bits (64 bytes).

🔗 Related Tools

📖 Where people get stuck

Enter a header, a payload and a secret, and this produces a signed JWT in the browser using the Web Crypto API (HS256, HS384 or HS512). Buttons add claims such as iat and exp. The secret is never sent to a server. There is one thing to understand about JWTs before anything elsea JWT is not encryption. The payload is merely Base64URL encoded, and anyone without any key at all can read it. The signature guarantees only that the contents were not altered; it guarantees nothing whatsoever about them not being seen.

Case What happens What to do
Pasting a production secret into a browser tool This page does not send values to a server, but "not transmitted" and "leaves no trace" are different claims. The string you type exists in the DOM, may persist in browser history and autofill, appears in screenshots and screen shares, and is readable by any extension you have installed. Copy it and it lands in your clipboard history tool as well. The most commonly overlooked item is the generated token itself: a JWT pasted into Slack or a ticket for debugging remains usable for as long as it is valid, even if the secret never leakeda JWT is a bearer token, so whoever holds it is treated as the subject. Only put a throwaway secret into this page. A value from the random-generate button is enough — if the point is to confirm how signing works, it does not have to be real. If you have already pasted a production secret, there is exactly one remedy: rotate it now. Leaving it on the assumption that it is probably fine gives you no way to determine later whether it leaked — and an HMAC secret can be brute-forced locally from a single captured token, so dictionary words and short strings are especially dangerous. Better still, design things so that a production secret is never seen by a human at allhave it read directly from an environment variable or a secret manager, and never create a copy-and-paste path in the first place.
exp only means something to the verifier exp is just a field; it is not a mechanism that makes a token stop working when the time arrivesit becomes an expiry only because the verifier reads the value and rejects the token. Four standard defects follow. (1) Forget exp and the token is valid forever. (2) Get the unit wrongtimes in a JWT are seconds since the epoch, while JavaScript Date.now() returns milliseconds, so passing it straight through points fifty thousand years into the future. (3) Clock skew between servers causes a freshly issued token to be rejected on its nbf. (4) An issued token cannot be revokedlogging out or changing the password does not stop it; it stays valid until exp. Keep the exp of an access token shortfifteen minutes to an hour is the usual guidance. Maintain long-lived login state with a refresh token instead, stored server-side so it can be invalidated individually. That is the only way to address the revocation problem head-on. If immediate revocation is a requirement, include a jti and keep a denylistbut at that point you have given up the stateless-server advantage that motivated JWT in the first place, so check whether the requirement is real before you build it. In the verifier, allow a leeway of some tens of seconds when comparing exp and nbf. And always use seconds — in JavaScript, Math.floor(Date.now() / 1000).
The verifier trusts the alg in the token The alg in the header sits in a place the attacker can rewritea library that reads it to decide how to verify is letting the attacker choose the verification method. Two well-known breaks exist. (1) alg: nonewrite the value meaning "unsigned" and leave the signature segment empty, and a naively implemented library accepts it. (2) RS256 and HS256 confusion — take a token meant to be verified with an RSA public key, rewrite alg to HS256 and sign it using the public key as the HMAC secret. Since the public key is public, the attacker can mint valid tokens at will. Both are implementation bugs, not flaws in JWT itself. In the verifier, pass the algorithm as a fixed value. Most libraries accept an argument such as algorithms: ['HS256']if the API lets you omit it, do not omit it. The alg you read from a token is not an input to verification; it is one of the things being verified. Pin the key in the same way, and if you rotate several keys, select by kid and always select from your own key set. Do not forget secret strength either: use at least 256 bits of randomness for HS256 and never a memorable passwordHMAC can be verified offline as many times as the attacker likes from a single token, which makes dictionary attacks a realistic threat. And finally, do not write the library yourself.

Do not put secrets in the payload. To repeat: anyone can read itput an email address, a phone number, a breakdown of permissions or internal IDs in there and you have published them to everyone who sees the token. Remember while designing that anyone can open browser DevTools and read the contents of their own token. Keep claims minimal and fetch details from the server when you actually need them. There are also many situations where a JWT is simply not the best fitfor an ordinary web application on a single domain, a server-side session is simpler and can log the user out instantly. Where JWT genuinely earns its place is authentication spanning several services, or an architecture where the verifier cannot call back to the issuer. "It is modern" is not a reasonchoose it based on whether you can accept the trade-off: statelessness in exchange for the inability to revoke.

📖 How to Use

  1. 1
    Set algorithm and payload
    Choose HS256 / HS384 / HS512 and enter your JSON claims in the Payload field. Use the +iat / +exp buttons to add standard claims in one click.
  2. 2
    Enter or generate a secret
    Type a key into the Secret field, or click Random to generate a cryptographically secure 256-bit secret. Select UTF-8, Base64, or Base64URL input format.
  3. 3
    Copy the generated JWT
    The signed JWT appears instantly in the right panel. Click Copy to get it on your clipboard, ready for JWT decoder or API testing.

❓ Frequently Asked Questions

What is the difference between HS256, HS384, HS512?
All use HMAC signing; the number indicates the SHA hash length. HS256 is the most common; HS512 is preferred when higher security is needed.
Is it safe to enter a production secret here?
The secret is only used by Web Crypto API in your browser and never sent to any server. That said, entering production secrets into web tools is generally discouraged — use for testing only.
Is RS256 or ES256 (asymmetric) supported?
This tool supports HMAC-based algorithms (HS256 / HS384 / HS512) only. For RS256, ES256 and other asymmetric algorithms, use a dedicated library.
🐛 Found a bug or issue with this tool?

Free to use, no signup. Even just the steps to reproduce are helpful. Reports go directly to the operator and help us fix issues.

* Browser info (UA / screen / language / URL) is sent automatically to help reproduce the issue