Sign a JWT without leaving your browser
A JSON Web Token (JWT) is three base64url-encoded parts joined by dots: a header, a payload of claims, and a signature. This tool builds all three from JSON you control and signs them with HS256 — HMAC using SHA-256 — using a secret you provide. Everything happens client-side through the browser’s Web Crypto API, so your secret is never transmitted. It is built for developers debugging auth flows, crafting test fixtures, or learning exactly how a JWT is assembled.
How it works
A JWT is computed as:
header_b64 = base64url(JSON header)
payload_b64 = base64url(JSON payload)
signing_input = header_b64 + "." + payload_b64
signature = base64url( HMAC_SHA256(secret, signing_input) )
token = signing_input + "." + signature
The alg field in the header is forced to HS256 so the declared algorithm
always matches the signature that is actually computed — a common source of
“invalid signature” bugs. Base64url is standard base64 with + replaced by
-, / replaced by _, and trailing = padding stripped. The HMAC step
uses crypto.subtle.sign with the UTF-8 bytes of your secret as the key.
Tips and notes
Common payload claims include sub (subject), iat (issued-at, a Unix
timestamp), and exp (expiry). Remember that a JWT is signed, not
encrypted — anyone can base64url-decode the payload and read it, so never
put secrets in the claims. To verify the token elsewhere, use the exact same
secret string. If a verifier rejects your token, check that the secret matches
byte-for-byte and that no extra whitespace crept into the JSON.