JWT Generator
Generates and signs a JSON Web Token with the claims, algorithm and key you define.
Family
Hash size
What "signing" a JWT means
Signing a JWT produces the third segment (the signature) from the already-encoded header and payload, using a key. Anyone can read the header and payload without that key (they're just Base64URL) — what the signature guarantees is that whoever created the token knew the key, and that header/payload weren't altered afterwards. A verifier with access to the same key (HMAC) or the matching public key (RSA/ECDSA) confirms this by recomputing the signature.
HMAC vs. RSA/ECDSA — which to use
HMAC (HS256/384/512) uses the same key (a secret) to sign and verify — simple, fast, but any service that needs to verify the token also needs to know the secret, which makes it risky to distribute to many services. RSA (RS*/PS*) and ECDSA (ES*) use a key pair: sign with the private key, verify with the public key — the public key can circulate freely, making this the right choice when several different services need to verify tokens issued by a single issuer. RSA-PSS (PS*) is a more modern RSA signature variant than RS* (PKCS#1 v1.5) — both are secure today, PSS is the recommendation for new systems.
Accepted private key format (PEM, PKCS8)
For RSA/RSA-PSS/ECDSA, the key must be PEM, PKCS8 format (starts with "-----BEGIN PRIVATE KEY-----"). A common mistake: a key generated with "openssl genrsa" or "openssl ecparam" comes out as PKCS1 (RSA, "-----BEGIN RSA PRIVATE KEY-----") or SEC1 (EC, "-----BEGIN EC PRIVATE KEY-----") — neither is accepted directly here. Convert it first: "openssl pkcs8 -topk8 -nocrypt -in key.pem -out key-pkcs8.pem".
Why the header isn't editable
A JWT header declares the algorithm ("alg") used to sign it. If that declaration could be freely edited, it would be possible to (accidentally) generate a token whose header states a different algorithm than the one actually used to compute the signature — a token no verifier would accept, and confusing to debug. That's why this tool's header is always built automatically from the algorithm chosen in the selector above.
The danger of "alg: none"
"none" is a legitimate algorithm per RFC 7518 — but it literally means "no signature". It's also the basis of one of the best-known attacks against JWT implementations: an attacker takes a signed token, swaps the header for "none" and empties the signature; a misconfigured verifier that trusts the algorithm declared by the token itself accepts it. Generating a "none" token here is only for local mocks/tests — never use a token generated this way against a system expecting a real signature.
Frequently asked questions
No. Signing happens entirely in your browser, using the native Web Crypto API — this tool makes no network calls. Even so, avoid pasting production secrets/keys into any web tool as a habit.
EdDSA support in the Web Crypto API is still inconsistent across browsers, so it isn't included in this version. HMAC, RSA (PKCS#1 v1.5 and PSS) and ECDSA cover every widely-supported algorithm.
Technically yes, if you generated it with a real algorithm (not "none") and a proper key — but this tool exists for development, testing and learning, not for issuing production tokens. Prefer generating production tokens on your backend, where the key never passes through a browser.
Both sign with an RSA private key and verify with the matching public key. RS256 uses the PKCS#1 v1.5 padding scheme (older); PS256 uses RSA-PSS (more modern, with a random salt). Both are considered secure today — PS256 is the recommendation for new systems, RS256 remains widely used for compatibility with legacy systems.
The most common cause is the key type not matching the chosen algorithm — for example, pasting an EC key while RS256 (which requires RSA) is selected. Also check that the key is PEM PKCS8 (see "Accepted private key format" above).
Not in this version — this tool expects you to already have a key (generated, for example, with openssl). Generating the pair directly in the tool is a candidate improvement for a future version.