JWT Encoder

Create and sign JSON Web Tokens with HS256, HS384, HS512

Header

Runs locally · Safe to paste secrets

Payload

Runs locally · Safe to paste secrets

Secret Key

Runs locally · Safe to paste secrets

Encoded JWT

Output will appear here…

Your secret key never leaves your browser. All signing happens client-side.

Also try:JWT Decoder

What Is JWT Encoding?

JWT encoding is the process of creating a JSON Web Token — a compact, URL-safe string that carries a set of claims signed with a cryptographic key. The result is a three-part token (header.payload.signature) defined by RFC 7519 that servers can verify without maintaining session state. JWT encoding online lets you build and sign tokens directly in your browser for testing and development.

The header declares the signing algorithm (e.g. HS256) and token type. The payload contains claims — key-value pairs such as the subject (sub), expiration time (exp), and any custom data your application needs. Both parts are serialized as JSON, then base64url-encoded. The signature is computed over the encoded header and payload using a secret key, binding all three segments together.

Unlike session cookies, JWTs are self-contained: the verifier does not need to query a database or call an external service. This makes JWT-based authentication popular in REST APIs, microservices, and single-page applications where stateless authorization reduces latency and simplifies horizontal scaling.

Why Use a JWT Encoder?

Generating JWTs by hand requires base64url encoding, JSON serialization, and HMAC computation. This tool handles all three steps instantly so you can focus on getting the claims right.

Instant Token Generation
Edit the header, payload, and secret — the signed JWT updates in real time. No build step, no library installation, no boilerplate code.
🔒
Multiple HMAC Algorithms
Switch between HS256, HS384, and HS512 with one click. The header updates automatically and the signature is recomputed immediately.
🛡️
Privacy-First Processing
All signing happens in your browser using the Web Crypto API. Your secret key and payload data never leave your machine — no server, no logs, no risk.
📋
One-Click Claim Helpers
Add iat, exp+1h, or exp+24h timestamps with a single button. No need to calculate Unix timestamps manually or look up the current epoch time.

JWT Encoder Use Cases

Frontend Authentication Testing
Generate tokens with specific claims and expiration times to test login flows, token refresh logic, and protected route guards without running a backend auth server.
Backend API Development
Create test tokens with custom sub, aud, and scope claims to exercise authorization middleware, role-based access control, and permission checks during local development.
DevOps & CI/CD Pipelines
Generate short-lived service tokens for deployment scripts, integration tests, or inter-service communication where a full OAuth flow would add unnecessary complexity.
QA & Manual Testing
Build tokens with edge-case claims — expired tokens, missing fields, wrong audiences — to verify that your API returns the correct HTTP 401 or 403 responses.
Security Auditing
Create tokens signed with different algorithms and secret lengths to validate that your verification logic correctly rejects weak or mismatched signatures.
Learning & Prototyping
Students and developers new to JWT can experiment with header fields, claim structures, and signing algorithms to understand how each part of the token works.

HS256 vs HS384 vs HS512: HMAC Algorithm Comparison

All three algorithms use HMAC (Hash-based Message Authentication Code) with a shared secret. The difference is the underlying hash function, which affects signature length and security margin. For most applications, HS256 provides sufficient security. Choose HS384 or HS512 when compliance requirements (e.g. FIPS-140) mandate a stronger hash or when your tokens carry high-value authorization decisions.

AlgorithmHashSignatureSpeedTypical use
HS256SHA-25632 BFastestGeneral purpose, default for most libraries
HS384SHA-38448 BFastHigher security margin, FIPS-140 compliant
HS512SHA-51264 BFastMaximum HMAC security, large payloads

Standard JWT Claims Reference

RFC 7519 defines seven registered claims. None are required, but using them correctly improves interoperability and security. The exp claim is especially important — tokens without an expiration are valid indefinitely if the secret is not rotated.

ClaimNameDescriptionExample
issIssuerWho issued the token"auth.example.com"
subSubjectWho the token represents"user-123"
audAudienceIntended recipient service"api.example.com"
expExpirationUnix timestamp — token invalid after this time1717203600
nbfNot BeforeUnix timestamp — token invalid before this time1717200000
iatIssued AtUnix timestamp when the token was created1717200000
jtiJWT IDUnique token identifier for revocation tracking"a1b2c3d4"

JWT Encoding in Code

These examples show how to create and sign JWTs programmatically. Each snippet produces a valid HS256-signed token. For production systems, always set the exp claim and use a cryptographically random secret of at least 256 bits.

JavaScript (Web Crypto API)
async function signJWT(payload, secret, alg = 'HS256') {
  const header = { alg, typ: 'JWT' }
  const enc = new TextEncoder()

  // Base64url encode header and payload
  const b64url = (obj) =>
    btoa(JSON.stringify(obj)).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')

  const h = b64url(header)
  const p = b64url(payload)

  // Sign with HMAC-SHA256
  const key = await crypto.subtle.importKey(
    'raw', enc.encode(secret),
    { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
  )
  const sig = await crypto.subtle.sign('HMAC', key, enc.encode(`${h}.${p}`))
  const s = btoa(String.fromCharCode(...new Uint8Array(sig)))
    .replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '')

  return `${h}.${p}.${s}`
}

// Usage
const token = await signJWT(
  { sub: 'user-123', name: 'Alice', iat: Math.floor(Date.now() / 1000) },
  'your-256-bit-secret'
)
// → "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi..."
Python (PyJWT)
import jwt
import time

payload = {
    "sub": "user-123",
    "name": "Alice",
    "iat": int(time.time()),
    "exp": int(time.time()) + 3600,  # expires in 1 hour
}

# Sign with HS256 (default)
token = jwt.encode(payload, "your-256-bit-secret", algorithm="HS256")
# → "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOi..."

# Verify and decode
decoded = jwt.decode(token, "your-256-bit-secret", algorithms=["HS256"])
# → {"sub": "user-123", "name": "Alice", "iat": 1717200000, "exp": 1717203600}
Node.js (jsonwebtoken)
const jwt = require('jsonwebtoken')

const payload = {
  sub: 'user-123',
  name: 'Alice',
  role: 'admin',
}

// Sign — iat is added automatically
const token = jwt.sign(payload, 'your-256-bit-secret', {
  algorithm: 'HS256',
  expiresIn: '1h',    // sets exp claim
  issuer: 'auth.example.com',  // sets iss claim
})

// Verify
const decoded = jwt.verify(token, 'your-256-bit-secret')
// → { sub: 'user-123', name: 'Alice', role: 'admin', iat: ..., exp: ... }
Go (golang-jwt)
package main

import (
    "fmt"
    "time"
    "github.com/golang-jwt/jwt/v5"
)

func main() {
    claims := jwt.MapClaims{
        "sub":  "user-123",
        "name": "Alice",
        "iat":  time.Now().Unix(),
        "exp":  time.Now().Add(time.Hour).Unix(),
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    signed, _ := token.SignedString([]byte("your-256-bit-secret"))
    fmt.Println(signed)
    // → eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOi...
}

Frequently Asked Questions

What is the difference between JWT encoding and JWT decoding?
JWT encoding creates a signed token from a header, payload, and secret key. JWT decoding reverses the process — it reads the base64url-encoded header and payload back into JSON. Decoding does not require the secret; encoding always does because the signature must be computed.
How long should my JWT secret key be?
For HS256, use a secret of at least 256 bits (32 bytes). For HS384, use at least 384 bits (48 bytes). For HS512, use at least 512 bits (64 bytes). Shorter secrets are technically accepted by most libraries but reduce the effective security of the HMAC signature. Generate secrets with a cryptographically secure random generator, not a human-chosen passphrase.
Is it safe to use this tool with real secret keys?
This tool processes everything in your browser using the Web Crypto API — no data is sent to any server. That said, avoid pasting production secrets into any web tool as a general security practice. For production key management, use environment variables or a secrets manager like HashiCorp Vault or AWS Secrets Manager.
Should I use HS256 or RS256 for my application?
Use HS256 when the same service both creates and verifies tokens — it is faster and simpler. Use RS256 (asymmetric) when third-party services need to verify your tokens without having the ability to create them. RS256 is common in OAuth 2.0 providers, OpenID Connect, and multi-tenant SaaS architectures.
Why does my JWT expire immediately after creation?
The exp claim uses Unix timestamps in seconds, not milliseconds. If you set exp to Date.now() (which returns milliseconds), the token will appear to expire thousands of years in the future — or if you accidentally use a millisecond value where seconds are expected, libraries may interpret it as already expired. Always use Math.floor(Date.now() / 1000) in JavaScript or int(time.time()) in Python.
Can I put sensitive data in the JWT payload?
You can, but you should not. The JWT payload is base64url-encoded, not encrypted — anyone with the token can read the claims. Do not store passwords, credit card numbers, or personal data in the payload. If you must include sensitive information, use JWE (JSON Web Encryption) as defined in RFC 7516, which encrypts the entire payload.
What happens if I change the payload after signing?
The signature becomes invalid. The HMAC signature is computed over the exact bytes of the encoded header and payload. Any change — even adding a space or changing a single character — produces a completely different signature. A properly implemented verifier will reject the token with a signature mismatch error.