RunLocalTools

JWT Builder & Signer — Create, Sign and Verify JWTs Online

Build and sign JWTs in your browser with HS256, RS256, PS256, ES256 and EdDSA. Claim helpers, test tokens, key export and verification. Free, no uploads.


What it does

The JWT Builder & Signer turns a header, a set of claims and a key into a signed JSON Web Token. You edit the header and payload as JSON, pick an algorithm, supply a secret or a private key, and the finished token appears as you type, colour-coded into header, payload and signature.

Beyond signing, it can verify a token against a secret, a public key or a JWKS, generate fresh keys, export them as PEM and JWK, produce a ready-made public JWKS, and create a pack of deliberately broken tokens (expired, tampered, unsigned and more) for testing your own authentication code.

How it works

Signing uses the Web Crypto API built into your browser, so there is no signing library to download. The token is the base64url-encoded header, a dot, the base64url-encoded payload, a dot, and the signature over those first two parts.

  • HS256 / HS384 / HS512 sign with HMAC and one shared secret. The secret can be entered as text, hex, base64 or base64url, and a random generator produces one at the recommended length (for API keys and other random strings, the Token generator offers more formats).
  • RS256 / RS384 / RS512 use RSA PKCS#1 v1.5 and PS256 / PS384 / PS512 use RSA-PSS with a salt the same length as the hash.
  • ES256 / ES384 / ES512 use ECDSA on P-256, P-384 and P-521. The signature is the raw r‖s pair JOSE requires, not the DER form some tools output.
  • EdDSA uses Ed25519 in browsers that support it.

Private keys can be pasted as PEM (PKCS#8, PKCS#1 BEGIN RSA PRIVATE KEY, or SEC1 BEGIN EC PRIVATE KEY) or as a JWK. After every signature the tool verifies the token against your key as a round-trip check. Verification enforces the algorithm you choose rather than trusting the token’s own alg header, and it refuses alg: none tokens, which guards against algorithm-confusion attacks.

Macros keep templates fresh. A value such as "{{now+1h}}" is replaced with the current time plus one hour each time you sign; {{now-5m}}, {{uuid}}, {{rand:16}} and {{n}} (a counter used in bulk mode) work the same way.

How to use it

  1. Choose an algorithm in the sidebar. For HS algorithms enter or generate a secret; for the others paste a private key, drop a key file, or click Generate key pair.
  2. Start from a template (minimal, OpenID Connect ID token, OAuth 2.0 access token per RFC 9068, service-to-service, email link) or edit the header and payload yourself.
  3. Use the claim buttons to set iat, nbf, exp (15 minutes to 30 days, or custom) and jti. Each time claim is shown as a readable date, with a plain-language warning if something looks off; if you only have a timestamp in another format, the Timestamp converter will translate it.
  4. Copy the token, the Authorization: Bearer header or a curl line, or copy the same token as Node (jose, jsonwebtoken) or Python (PyJWT) code.
  5. Open Verify to check a token (if you only want to read what is inside one, the JWT decoder is quicker), Test & bulk to generate test tokens or up to 100 tokens at once, and Keys to export the public JWKS, PEM and JWK versions of your key.

Test tokens for your auth middleware

One click produces seven labelled tokens signed with your key: a valid one, an expired one, one that is not valid yet (nbf in the future), one with a tampered payload, one with an altered signature, an unsigned alg: none token, and one with no exp. Send them to your API and confirm each is accepted or rejected as labelled. If a token your server should reject is accepted, you have found a bug before an attacker does.

Supported formats

  • Algorithms: HS256, HS384, HS512, RS256, RS384, RS512, PS256, PS384, PS512, ES256, ES384, ES512, EdDSA (Ed25519), plus none behind an explicit confirmation.
  • Private keys: PKCS#8 PEM, PKCS#1 RSA PEM, SEC1 EC PEM, JWK, or a one-key JWKS. Public keys (Verify): SPKI PEM, PKCS#1 RSA public PEM, JWK, JWKS (the key is chosen by kid when present).
  • Export: PKCS#8 and SPKI PEM, JWK, public JWKS, RFC 7638 JWK thumbprint (usable as kid), and an oct JWK for HMAC secrets.

Limitations

  • Signed tokens only (three parts). Encrypted tokens (JWE) and ES256K are not supported.
  • Password-protected PEM keys and X.509 certificates are not accepted; decrypt the key or paste the public key instead.
  • The token is signed from compact JSON, so whitespace is removed and key order is kept. Integers above 2^53 lose precision in JSON; put large IDs in strings (the tool warns you).
  • Ed25519 needs a current Chrome, Edge, Firefox or Safari. Web Crypto only works on HTTPS pages.
  • Unsigned (alg: none) tokens are provided for testing only and must never be trusted by a server.

FAQ

Is it safe to paste a real signing key or secret here?

Signing happens entirely in your browser and nothing you type is sent anywhere. Even so, treat any web page as a risk surface: browser extensions can read page contents, so use a throwaway or test key when you can, and keep production keys in your own secrets manager. By default the tool does not store your secret or private key; saving it is an opt-in checkbox.

Which algorithm should I choose?

Use HS256 when a single service both issues and checks the token and can keep a shared secret private. Use RS256, PS256, ES256 or EdDSA when other services must verify tokens without being able to forge them, because they only need the public key. ES256 and EdDSA give much shorter signatures than RSA at similar security.

The tool says the signature is verified, but my server rejects the token. Why?

The signature is only one check. Look at the algorithm the server expects, the key or kid it uses, iss and aud values, exp and nbf against its clock, and whether it demands claims you left out. The Verify tab can check iss, aud and clock skew, and the test tokens show how your server handles each failure.

What do macros like {{now+1h}} do?

They are replaced when a token is signed. "{{now}}" becomes the current time in seconds, {{now+1h}} adds an hour (units s, m, h, d, w), {{uuid}} and {{rand:16}} give fresh random values, and {{n}} counts 1, 2, 3… in bulk mode. Wrapped in quotes as a whole value they become plain numbers, so templates stay valid JSON.

Why is my ES256 signature 64 bytes when other tools show a longer one?

JOSE defines ECDSA signatures as the raw r and s values joined together (64 bytes for ES256, 96 for ES384, 132 for ES512). Some libraries output a DER-encoded signature instead, which is longer and not valid in a JWT. This tool produces and expects the raw form.

Can I check a token against a JWKS from my identity provider?

Yes. Paste the JWKS JSON into the Verify tab and the matching key is picked by kid. There is also an optional step that fetches a JWKS URL for you; it is off by default and described in the Privacy section below.

Privacy

Everything in this tool is local: building, signing, verifying with a pasted key or JWKS, key generation, key export, test tokens and bulk generation all run in your browser with its built-in Web Crypto. No libraries are downloaded from a CDN, and your tokens, secrets and keys are never uploaded.

One optional feature uses the internet: in the Verify tab, “Fetch a JWKS from a URL” is switched off until you tick its checkbox. When ticked, it requests the URL you enter (and, for an OpenID .well-known/openid-configuration address, the jwks_uri listed inside it). Your token, secret and private keys are never part of that request. Servers that do not allow cross-origin requests will refuse it; paste the JWKS instead.

Your header and payload drafts, templates, algorithm and display settings, and any public verification key are saved in this browser so they survive a refresh. Your secret and private key are not saved unless you tick “Remember my signing key in this browser”, which stores them unencrypted in this browser only. A “Clear all saved data” button deletes everything the tool has saved.