JWT Encoder
Free online JWT encoder — build and sign a JSON Web Token with HS256 (HMAC-SHA256). Edit the header and payload, enter a secret, and get a signed JWT instantly. Uses the browser's native Web Crypto API — nothing you type here is ever sent to a server.
Algorithm
Symmetric signing — the same secret signs and verifies the token.
Load example
JWT structure
Runs in your browser
Signing happens locally via the Web Crypto API. Your secret, header, and payload are never sent to any server.
Never sent anywhere — the secret is used only in-browser via crypto.subtle to compute the HMAC signature.
Signed JWT
What is a JWT and why sign one?
A JWT (JSON Web Token) is an open standard (RFC 7519) for transmitting information as a compact, URL-safe JSON object. Signing a JWT proves it was issued by whoever holds the signing key and that its contents have not been altered in transit. This encoder builds that signature for you: it takes a header and payload you edit, base64url-encodes them, and signs the result with HMAC-SHA256 (HS256) using a secret you supply.
Signing a JWT is useful when you need to test an API that expects a bearer token, prototype an authentication flow, or simply understand how the three parts of a token fit together before wiring up a server-side library.
How HS256 signing works
HS256 stands for HMAC using SHA-256 — a symmetric algorithm where the same secret both signs and verifies the token. The process is three steps:
1. Encode
The header and payload JSON objects are each serialized with no extra whitespace, then base64url-encoded (standard base64 with + → -, / → _, and padding = removed) and joined with a dot: headerB64.payloadB64.
2. Sign
The joined string is passed through HMAC-SHA256 using your secret as the key. In the browser this is done with the native crypto.subtle API — no external library needed.
3. Append
The raw signature bytes are base64url-encoded and appended as the third segment, producing the final header.payload.signature token.
Change a single character in the header or payload and the signature changes completely — that's what makes a signed JWT tamper-evident.
How to sign a JWT with the Web Crypto API
This is the same approach this tool uses internally — no JWT library, just the browser's built-in cryptography:
function base64url(bytes) {
let binary = '';
bytes.forEach(b => binary += String.fromCharCode(b));
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
}
async function signJWT(header, payload, secret) {
const enc = new TextEncoder();
const headerB64 = base64url(enc.encode(JSON.stringify(header)));
const payloadB64 = base64url(enc.encode(JSON.stringify(payload)));
const signingInput = headerB64 + '.' + payloadB64;
const key = await crypto.subtle.importKey(
'raw', enc.encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false, ['sign']
);
const sigBuffer = await crypto.subtle.sign('HMAC', key, enc.encode(signingInput));
const signature = base64url(new Uint8Array(sigBuffer));
return signingInput + '.' + signature;
}
const token = await signJWT(
{ alg: 'HS256', typ: 'JWT' },
{ sub: '1234567890', name: 'John Doe', iat: 1516239022 },
'your-256-bit-secret'
);
Already have a token and need to inspect it instead of creating one? Use our JWT decoder to decode the header, payload, and claims of an existing JWT.
Security notes
- Don't treat this as a production secret generator. Use it to learn how JWT signing works or to build test tokens for local development — not to generate real credentials without understanding your own application's security requirements.
- Use a strong, random secret. For HS256, the secret should be at least 256 bits (32 random bytes) of entropy. Short or guessable secrets can be brute-forced.
- Never store sensitive data in the payload. The payload is only base64url-encoded, not encrypted — anyone with the token can read it.
- Set an expiry (
exp). Tokens without an expiration are valid indefinitely once issued. - Keep signing secrets server-side in production. If both the client and server hold the same HS256 secret, either side can forge tokens. For public clients, prefer an asymmetric algorithm like RS256 or ES256.