Skip to content

JWT Encoder & Generator

Free online JWT generator & encoder. Build the header and payload, sign with HS256, RS256, or ES256 instantly. 100% in-browser — your secret and key never leave your device.

No Tracking Runs in Browser Free
Payload (Claims)
Insert a registered claim:
Secret
Signed locally in your browser — your secret and private key never leave your device.
Follows RFC 7515/7518 signing behavior with output cross-verified against an independent public-key verifier — Go Tools Security Team · Jun 11, 2026

What is a JWT Encoder?

A JWT encoder builds and cryptographically signs a JSON Web Token from a header and a payload of claims. A JWT, defined in RFC 7519, is three Base64URL-encoded sections joined by dots: header.payload.signature. The header names the signing algorithm; the payload carries the claims (who the token is about, what it can do, when it expires); and the signature is a cryptographic proof, computed over the header and payload with a secret or private key, that lets a recipient detect tampering.

"JSON Web Token (JWT) is a compact claims representation format intended for space-constrained environments such as HTTP Authorization headers and URI query parameters." — RFC 7519, Section 1

Encoding is the inverse of decoding. A JWT decoder reads an existing token's claims; an encoder takes claims you supply and produces a brand-new signed token. The signing step is what separates a real JWT from arbitrary Base64 — without a valid signature, no verifier will accept the token. This tool signs using the browser's native Web Crypto API across the HMAC (HS), RSA (RS, PS), and ECDSA (ES) families, so the entire operation happens on your device with zero dependencies and zero network calls.

Developers reach for a JWT encoder constantly: to mint a token that exercises a protected API endpoint, to reproduce the exact claim shape an OAuth server issues so a bug can be debugged, to build fixtures for integration tests, or to hand a teammate a ready-to-use Bearer token for a curl command. Because the payload is encoded, not encrypted, a JWT is safe to pass over the network but must never carry secrets — anyone with the token can read every claim, and only the signature stops them from changing one.

JWT work pairs naturally with other developer tools. After signing, decode the token to confirm its claims, convert exp and iat between Unix time and human dates, or compute a SHA-256 hash when you need the underlying hash function that HS256's HMAC is built on. Because every JWT segment is Base64URL-encoded, a Base64 tool is handy when you inspect a token by hand; for an in-depth look at the encoding, see our Base64 fundamentals guide.

// Sign a JWT in the browser with the Web Crypto API (HS256)
async function encodeJwt(payload, secret) {
  const b64url = (bytes) =>
    btoa(String.fromCharCode(...new Uint8Array(bytes)))
      .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
  const enc = (obj) =>
    b64url(new TextEncoder().encode(JSON.stringify(obj)));

  const header = { alg: 'HS256', typ: 'JWT' };
  const signingInput = `${enc(header)}.${enc(payload)}`;

  const key = await crypto.subtle.importKey(
    'raw', new TextEncoder().encode(secret),
    { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
  const sig = await crypto.subtle.sign(
    'HMAC', key, new TextEncoder().encode(signingInput));

  return `${signingInput}.${b64url(sig)}`;
}

const token = await encodeJwt({ sub: 'user_123', exp: 1999999999 }, 'my-secret');
// → eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsImV4cCI6MTk5OTk5OTk5OX0....

Key Features

Generate & Sign JWTs Instantly

Edit the payload and watch the signed token update in real time — header, payload, and signature computed on the fly. No Generate button, no round-trip to a server.

Full Algorithm Coverage

Sign with HS256/384/512, RS256/384/512, PS256/384/512, and ES256/384/512 — every common JWS family, all via the browser's native Web Crypto API.

Keys Never Leave Your Device

Your secret and PKCS8 private key are used entirely in-browser. Nothing is uploaded, logged, or stored — safe for development and incident response.

Quick-Claim Helpers

Insert iss, sub, aud, iat, nbf, or a one-hour exp with a single click — no manual Unix timestamps, no syntax slips.

Color-Coded Output

The signed token is segmented into header, payload, and signature with distinct colors, so the structure is obvious at a glance and easy to copy.

Zero Dependencies

Built only on the browser's Web Crypto API and JSON — no external libraries, no telemetry, no network calls of any kind.

Examples

HS256 Session Token

{
  "sub": "user_123",
  "name": "Alice",
  "role": "admin",
  "iat": 1715000000,
  "exp": 1999999999
}
secret: a-string-secret-at-least-256-bits-long
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyXzEyMyIsIm5hbWUiOiJBbGljZSIsInJvbGUiOiJhZG1pbiIsImlhdCI6MTcxNTAwMDAwMCwiZXhwIjoxOTk5OTk5OTk5fQ.<HMAC-SHA256 signature>

An HMAC-SHA256 token signed with a shared secret — the most common setup for stateless session authentication. Anyone holding the same secret can verify it.

RS256 Access Token

{
  "iss": "https://auth.example.com",
  "aud": "api.example.com",
  "sub": "90087165",
  "scope": "read:user write:post",
  "iat": 1715000000,
  "exp": 1999999999
}
private key: -----BEGIN PRIVATE KEY----- (PKCS8)
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJodHRwczovL2F1dGguZXhhbXBsZS5jb20iLCJhdWQiOiJhcGkuZXhhbXBsZS5jb20iLCJzdWIiOiI5MDA4NzE2NSIsInNjb3BlIjoicmVhZDp1c2VyIHdyaXRlOnBvc3QiLCJpYXQiOjE3MTUwMDAwMDAsImV4cCI6MTk5OTk5OTk5OX0.<RSA signature>

An RSA-signed OAuth-style access token. The token is signed with your private key and verified by anyone holding the matching public key — ideal when the verifier should not be able to mint tokens.

ES256 Compact Token

{
  "sub": "device-42",
  "iat": 1715000000,
  "exp": 1999999999
}
private key: -----BEGIN PRIVATE KEY----- (P-256)
eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJkZXZpY2UtNDIiLCJpYXQiOjE3MTUwMDAwMDAsImV4cCI6MTk5OTk5OTk5OX0.<ECDSA P-256 signature>

An ECDSA token on the P-256 curve. ES256 signatures are far shorter than RSA while offering equivalent security, which keeps the token small for constrained environments.

How to Use

  1. 1

    Edit the Payload Claims

    Write the claims your token needs as JSON in the payload editor. Use the quick-claim chips to insert iss, sub, aud, iat, nbf, or a one-hour exp without typing timestamps.

  2. 2

    Choose Algorithm & Enter the Key

    Pick a signing algorithm. For HS256/384/512 enter a secret; for RS, PS, or ES algorithms paste a PKCS8 PEM private key. The token is signed locally as you type.

  3. 3

    Copy the Signed JWT

    The signed token appears instantly, color-coded by segment. Click Copy to lift it into an Authorization header, curl command, or test. Your key never left your browser.

Common Errors

Using a Weak HMAC Secret

HS256 security depends entirely on secret entropy. A short or guessable secret lets attackers brute-force it and forge tokens. Use at least 256 bits of randomness.

✗ Wrong
secret: "password123"  // guessable, low entropy
✓ Correct
secret: base64(crypto.randomBytes(32))  // >=256 random bits

Omitting the exp Claim

A token with no exp never expires. If it leaks, there is no natural revocation point. Always set an expiration appropriate to the token type.

✗ Wrong
{ "sub": "user_123", "role": "admin" }  // no exp
✓ Correct
{ "sub": "user_123", "role": "admin", "exp": 1715003600 }

Pasting a PKCS1 Key Instead of PKCS8

The Web Crypto API imports only PKCS8 private keys. A traditional RSA PKCS1 key fails to import — convert it first.

✗ Wrong
-----BEGIN RSA PRIVATE KEY-----  // PKCS1, not supported
✓ Correct
openssl pkcs8 -topk8 -nocrypt -in pkcs1.pem -out pkcs8.pem

Common Use Cases

Generate Tokens for API Testing
Generate an HS256 Bearer token in seconds to exercise a protected endpoint from curl, Postman, or an integration test.
Reproduce OAuth & OIDC Tokens
Build an RS256 or ES256 token that mirrors what your authorization server issues, so you can debug claim and audience mismatches.
Create Test Fixtures
Produce deterministic signed tokens for unit and integration tests without standing up a full auth server.
Debug Authorization Failures
Recreate a customer's token shape — issuer, audience, scope, expiration — to find why a backend rejects it.
Validate a Verifier
Sign tokens with a known key to confirm your verification middleware accepts valid tokens and rejects tampered ones.
Prototype Auth Flows
Hand teammates ready-to-use tokens while wiring up a new login, microservice, or service-to-service call.

Technical Details

RFC 7519 / 7515 / 7518 Compliant
Produces JWS tokens conforming to RFC 7519 (JWT), RFC 7515 (JWS), and RFC 7518 (JWA), with the registered algorithm identifiers in the header.
Native Web Crypto Signing
Signs via crypto.subtle for HMAC, RSASSA-PKCS1-v1_5, RSA-PSS, and ECDSA. ECDSA signatures are emitted as raw r||s, exactly as JWS requires.
Base64URL, Zero Dependencies
Header and payload are Base64URL-encoded with the URL-safe alphabet (RFC 4648), no padding. No external libraries, no network calls, no telemetry.

Best Practices

Always Set an Expiration
Include an exp claim so a leaked token stops being valid. Short lifetimes shrink the blast radius — minutes for access tokens, not days.
Keep Secrets Out of the Payload
A JWT payload is readable by anyone with the token. Put identifiers and scopes in it; never passwords, API keys, or full PII.
Sign Server-Side in Production
Use this tool for tests and debugging. In real systems, sign tokens on the server with a maintained library and a key from your secrets manager.

Frequently Asked Questions

How do I generate a JWT online?
Edit the payload JSON in the box above, choose a signing algorithm (HS256 is the default and needs only a secret), and enter your secret or paste a PKCS8 PEM private key. The signed token appears instantly, with the header, payload, and signature segments color-coded so you can copy the whole thing with one click. Signing runs entirely in your browser using the native Web Crypto API — there is no Generate button to wait on and no request to a server, so it is safe to sign tokens with real keys during development.
What is a JWT generator?
A JWT generator is a tool that builds and cryptographically signs a JSON Web Token from a header and a payload of claims, producing a header.payload.signature string you can use as a Bearer token. It is the inverse of a JWT decoder: instead of reading an existing token, it creates a new one signed with your secret (HS256) or private key (RS256/ES256). This generator runs entirely in your browser, so the token is produced instantly and your signing key never leaves your device.
Is this JWT generator free and safe to use?
Yes — it is completely free, with no signup, no ads, and no tracking. It is safe because all signing happens locally in your browser via the Web Crypto API: your payload, secret, and private key are never uploaded, logged, or stored, and the tool makes no network requests at all. That makes it suitable even when you are working with sensitive keys, though using disposable test keys is always the safest habit.
Is it safe to enter my secret or private key here?
Yes. Signing happens locally in your browser; your secret and private key are never sent to a server, never logged, never stored, and never used for analytics. There are no cookies and no tracking. This matters because a JWT signing key can mint valid credentials — pasting it into a remote tool would be equivalent to handing over the keys to your auth system. Because everything runs client-side, this encoder is safe to use with production keys, but you should still prefer disposable or test keys whenever possible.
What is the difference between HS256 and RS256?
HS256 (HMAC-SHA256) uses a single shared secret to both sign and verify. It is simple and fast, but every party that can verify the token can also create one, so the secret must stay on trusted servers only. RS256 (RSA-SHA256) uses a key pair: you sign with a private key and others verify with the public key. This lets you distribute the public key freely — to client apps, partner services, or a JWKS endpoint — without giving anyone the ability to forge tokens. Use HS256 for symmetric, single-owner systems; use RS256 or ES256 when verifiers should not be able to mint tokens.
Which algorithms does this JWT encoder support?
It signs with HS256, HS384, HS512 (HMAC with a shared secret), RS256, RS384, RS512 (RSA PKCS#1 v1.5), PS256, PS384, PS512 (RSA-PSS), and ES256, ES384, ES512 (ECDSA on P-256, P-384, and P-521). All of them are produced with the browser's native Web Crypto API, so there are no third-party libraries and nothing leaves your machine. HMAC algorithms take a text or Base64 secret; the RSA and ECDSA families take a PKCS8 PEM private key.
How do I set the exp (expiration) claim?
Add an exp claim to the payload as a Unix timestamp in seconds — for example "exp": 1999999999. The quickest way is the exp +1h chip below the payload, which inserts an expiration one hour from now. You can also add iat (issued-at) and nbf (not-before) the same way. Remember that exp is in seconds, not milliseconds, and that verifiers compare it against their own clock, so keep server times in sync to avoid premature rejections. To convert a human date to a Unix timestamp, use our Unix timestamp converter.
How do I get a PKCS8 PEM private key for RS256 or ES256?
For RSA: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048 -out private.pem. For ECDSA P-256: openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out ec-private.pem. Both commands emit a PKCS8 PEM block beginning with -----BEGIN PRIVATE KEY-----, which is exactly what this tool expects. Paste the whole block, including the header and footer lines. The matching public key — used to verify the token — can be derived with openssl pkey -in private.pem -pubout.
How do I verify the token I just generated?
Paste it into our JWT decoder to confirm the header and payload decode as expected. To verify the signature, use your server or an SDK with the correct key: jwt.verify(token, secretOrPublicKey, { algorithms: ['HS256'] }) in Node.js, PyJWT.decode(token, key, algorithms=['RS256']) in Python, or jwt.Parse(token, keyFunc) in Go. Never verify with an empty algorithm list or with verify_signature=False in production — always pin the exact algorithm you expect.
What should I put in the payload?
Keep it lean. The registered claims from RFC 7519 are iss (issuer), sub (subject — usually a user ID), aud (audience), exp (expiration), nbf (not before), iat (issued at), and jti (token ID). Alongside these you can add application claims like role, scope, or email. Do not put secrets in the payload — a JWT is encoded, not encrypted, so anyone with the token can read every claim. Keep tokens under about 4 KB so they fit in Authorization headers and cookies.
Is a JWT encrypted?
No. A standard signed JWT (a JWS) is Base64URL-encoded, not encrypted. The signature proves the token has not been tampered with and was issued by someone holding the key, but the header and payload are fully readable by anyone who has the token. If you need the payload itself to be confidential, you need a JWE (encrypted JWT), which is a different format. This tool produces signed JWS tokens, the kind used for the vast majority of authentication and authorization flows.
Why is my RS256 or ES256 signing failing?
The most common causes are: (1) the key is not in PKCS8 format — convert a traditional -----BEGIN RSA PRIVATE KEY----- (PKCS1) key with openssl pkcs8 -topk8 -nocrypt -in old.pem -out pkcs8.pem; (2) the curve does not match the algorithm — ES256 needs a P-256 key, ES384 needs P-384, ES512 needs P-521; (3) you pasted a public key or a certificate instead of the private key; or (4) the key is encrypted with a passphrase, which the Web Crypto API cannot import directly. Decrypt it first with openssl pkey and paste the unencrypted PKCS8 block.
Does this tool support the alg:none unsigned token?
No, and deliberately so. An alg:none token has no signature, which means anyone can forge one — it is the root of a classic JWT authentication-bypass vulnerability. Because the entire point of an encoder is to produce a signed token, this tool only offers real signing algorithms. If you are studying alg:none for security research, you can construct one by hand by Base64URL-encoding the header and payload and leaving the signature segment empty — the token still ends with a trailing dot (header.payload.) — but you should never accept such a token in production.
Can I generate a JWT in code instead?
Yes. In Node.js: jsonwebtoken.sign(payload, secret, { algorithm: 'HS256', expiresIn: '1h' }). In Python: jwt.encode(payload, key, algorithm='RS256') with PyJWT. In Go: jwt.NewWithClaims(jwt.SigningMethodES256, claims).SignedString(privateKey). This tool is the fastest way to produce a token for a quick test, a curl request, or a fixture — but in application code you should generate tokens server-side with a maintained library and a key loaded from your secrets manager, never hard-coded.

Related Tools

View all tools →