Browser-only tool

JWT Encoder & Signer

Edit the JOSE header and claims payload, choose an HMAC, RSA, RSA-PSS, or ECDSA algorithm, then create a signed three-part JWT locally with Web Crypto.

Runs locally in your browser · No upload · No account

HS uses a shared secret. RS, PS, and ES require a PEM PKCS#8 private key.

Do not paste production secrets or private keys into a browser utility. Use a maintained JWT library and protected server-side key storage in production.

Build the exact header, payload, and signature

The encoder serializes each JSON object without whitespace, applies unpadded Base64URL encoding, joins the two segments with a dot, and signs that exact ASCII input. The selected algorithm replaces the header alg value so the control and generated token cannot silently disagree.

Quick actions can add the current iat NumericDate and an exp value one hour later. These values are only editing conveniences. A production issuer should set issuer, subject, audience, lifetime, token identifier, and other claims from its own authenticated server-side policy.

Use browser generation for debugging, not key operations

HMAC signing accepts a UTF-8 or Base64URL-encoded secret. RSA and ECDSA signing accept a PEM PKCS#8 private key, including RSA PRIVATE KEY input converted locally to PKCS#8. The generated token, JSON, and key remain in this browser tab.

Do not paste production secrets or private keys into a general-purpose browser tool. Browser-local processing avoids a network upload, but extensions, clipboard history, screen sharing, device compromise, and reused secrets remain risks. Prefer a maintained JWT library and managed key storage in production.

Common failures this tool explains

  • The header or payload is invalid JSON or is not a JSON object.
  • The selected algorithm does not match the supplied secret or private-key type.
  • A PEM key is incomplete, encrypted, or not in a browser-supported PKCS#8/RSA format.
  • A generated token is used as production authentication without server-side issuer, audience, lifetime, and key controls.

Equivalent commands

Use the runtime or shell already available in your workflow. Validate untrusted input and keep binary output out of terminals.

Python

import base64, hashlib, hmac, json
b64 = lambda value: base64.urlsafe_b64encode(value).rstrip(b'=').decode()
body = '.'.join([b64(json.dumps(header, separators=(',', ':')).encode()), b64(json.dumps(payload, separators=(',', ':')).encode())])
token = body + '.' + b64(hmac.new(secret, body.encode(), hashlib.sha256).digest())

JavaScript

import { createHmac } from 'node:crypto';
const b64 = value => Buffer.from(JSON.stringify(value)).toString('base64url');
const body = `${b64(header)}.${b64(payload)}`;
const token = `${body}.${createHmac('sha256', secret).update(body).digest('base64url')}`;

Shell

b64url() { openssl base64 -A | tr '+/' '-_' | tr -d '='; }
body="$(printf '%s' "$HEADER" | b64url).$(printf '%s' "$PAYLOAD" | b64url)"
sig=$(printf '%s' "$body" | openssl dgst -sha256 -mac HMAC -macopt "key:$SECRET" -binary | b64url)

Standards and official references