DevTools Logo

JWT Signer

JWT Signer

Create and sign JSON Web Tokens with HMAC algorithms using the Web Crypto API.

Algorithm & Secret

Payload

Examples

Sign a minimal HS256 token

Input
Header: {"alg":"HS256","typ":"JWT"}
Custom claims: {"sub":"1234567890","name":"John Doe"}
Standard claims: iss=my-app · iat=on · exp=1h
Secret: my-secret
Output
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoibXktYXBwIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9.hbu1TpKJFnZfdylQNQ-S-NTXdXyxIXj9gQKNUF0SB8s

The tool encodes header.payload as Base64URL, signs with HMAC-SHA-256, and concatenates all three parts. The example was computed at a fixed timestamp so the bytes are reproducible; the live tool inserts the current iat/exp each time you click Sign.

Decoding the same token back

Input
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaXNzIjoibXktYXBwIiwiaWF0IjoxNzAwMDAwMDAwLCJleHAiOjE3MDAwMDM2MDB9.hbu1TpKJFnZfdylQNQ-S-NTXdXyxIXj9gQKNUF0SB8s
Output
Header  {"alg":"HS256","typ":"JWT"}
Payload {"sub":"1234567890","name":"John Doe","iss":"my-app","iat":1700000000,"exp":1700003600}

Paste the token into /jwt-decoder (or any JWT library) to Base64URL-decode the two parts back to JSON. The signature segment is only needed for verification, not decoding.

Invalid JSON in custom claims is ignored

Input
Custom claims: {"sub":"42","role":"admin",  <-- malformed JSON

The tool surfaces 'Invalid JSON' under the textarea and disables the Sign button until the payload parses. Partial or invalid input never produces a malformed token.

About this tool

A JSON Web Token (JWT) is a compact, URL-safe token used everywhere for stateless authentication and authorization. A signed token has three Base64URL-encoded parts separated by dots — a header declaring the algorithm and token type, a payload of claims, and a signature produced by hashing the header.payload string with a secret (HMAC) or a private key (RSA/ECDSA). The token is verifiable by anyone who holds the secret or key, so anyone can read the header and payload but only the holder of the secret can produce a valid signature.

This tool signs JWTs locally in your browser with the Web Crypto API. It supports the three HMAC algorithms defined by RFC 7518 — HS256 (HMAC-SHA-256), HS384 (HMAC-SHA-384) and HS512 (HMAC-SHA-512) — and exposes the registered claims iss, sub, aud, iat and exp alongside a free-form JSON claim block. A built-in secret generator creates a cryptographically strong key from the same Web Crypto primitive, so you never have to invent a weak password.

Generation is fully client-side: the payload, secret and resulting token never leave your device. When you're done, copy the token into your Authorization header, hand it to a teammate, or send it straight to /jwt-decoder on this site to inspect what you just built.

How to use

  1. Choose an algorithm and a secret

    Pick HS256, HS384 or HS512 and either paste your own secret or click the refresh icon to generate a strong random key with the Web Crypto API.

  2. Fill in your claims

    Edit the custom-claims JSON for your application-specific data and set the standard fields — issuer (iss), subject (sub), audience (aud). Toggle iat on to add the issued-at claim, and pick an expiration (1h / 24h / 7d / 30d / none).

  3. Sign and copy the JWT

    Click Sign JWT. The tool Base64URL-encodes the header and payload, signs header.payload with HMAC and concatenates the three parts. Copy the result into your Authorization: Bearer header.

  4. Decode it back

    Use the built-in link to open the token in /jwt-decoder — it parses the same header and payload bytes and shows the registered claims in human-readable form.

Use cases

Bootstrapping a development JWT for local APIs

Mint a short-lived token with the iss/aud your API expects, paste it into Authorization: Bearer, and exercise your auth middleware without standing up an IdP.

Reproducing an issue from a staging token

Paste the same payload and secret the backend used, sign a fresh token, and replay the request with deterministic claims to isolate a bug.

Teaching the JWT structure

Sign a token and immediately decode it on /jwt-decoder so learners can see header, payload and signature side by side and learn why the payload is only Base64URL-encoded, not encrypted.

Generating a strong shared secret

Click the refresh icon next to the secret field to produce a 64-character hex key from crypto.subtle.generateKey — usable as an HMAC secret anywhere you need one.

Supported algorithms

AlgorithmWhat it does
HS256HMAC-SHA-256 — the default and most widely used
HS384HMAC-SHA-384 — stronger digest
HS512HMAC-SHA-512 — strongest HMAC variant

Secrets are generated with crypto.subtle.generateKey — cryptographically strong and never transmitted.

Common mistakes

Mistake:Treating the JWT payload as encrypted.

Fix:The payload is only Base64URL-encoded — anyone holding the token can read it. Never put passwords, PII or secrets in a JWT claim unless the token is additionally encrypted (JWE).

Mistake:Reusing a weak or guessable HMAC secret.

Fix:Use the built-in generator (crypto.subtle) or supply at least 32 random bytes for HS256. An attacker who guesses the secret can mint arbitrary tokens.

Mistake:Forgetting to set exp and shipping eternal tokens.

Fix:Pick a 1h / 24h / 7d expiration when you sign, and verify exp on the server. Without it a leaked token is valid forever.

Mistake:Putting timestamps as ISO strings instead of NumericDate.

Fix:RFC 7519 requires iat/exp/nbf to be Unix-seconds integers. The tool sets these correctly; if you add custom claims, keep them numeric or strings.

Frequently asked questions

References & standards