JWT Encoder

Build and sign JSON Web Tokens online. Choose HS256 or unsigned (none). Perfect for testing authentication flows and learning JWT structure.

Standard header with alg and optional typ. You can change alg to "none" but must match algorithm selection below.
Claims (registered or custom). You can also use the tool above to quickly populate from URL parameters (duplicate parameters are merged into arrays).
? Basic HS256 ⏱️ With expiration ? Unsecured (none)
Generated JWT
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
HS256 Length: 153 chars

How it's built:

base64Url(header) + "." + base64Url(payload) + "." + signature

? How to Encode a JWT (Comprehensive Guide)

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact, URL-safe way to represent claims between parties. Encoding a JWT involves creating a three-part structure: Header, Payload, and Signature. Below we explain each part in detail, provide examples, and discuss best practices.

1. Construct the Header

The header is a JSON object that describes the cryptographic operations applied to the token. The most common fields are:

  • alg (required): The signing algorithm, e.g., "HS256" (HMAC-SHA256), "RS256" (RSA-SHA256), or "none" (no signature).
  • typ (optional): The media type of the token. Typically "JWT" to explicitly state it's a JWT.
  • cty (optional): Content type – used when the token contains nested JWTs.

Example header:

{
  "alg": "HS256",
  "typ": "JWT"
}

You may also include custom header parameters (e.g., kid for key ID), but they must be understood by both parties.

2. Construct the Payload

The payload contains the claims – statements about the entity (usually the user) and additional metadata. Claims can be registered, public, or private.

Registered Claim Names (IANA standard)
Claim Name Description Example
iss Issuer Identifies the principal that issued the JWT. "iss": "https://auth.example.com"
sub Subject The subject of the JWT (e.g., user ID). "sub": "user123"
aud Audience Recipient(s) for which the JWT is intended. Can be an array. "aud": ["api.example.com"]
exp Expiration Time Unix timestamp (seconds) after which the token is invalid. "exp": 1893456000
nbf Not Before Unix timestamp before which the token must not be accepted. "nbf": 1672531200
iat Issued At Unix timestamp of token issuance. "iat": 1672531200
jti JWT ID Unique identifier; prevents replay attacks. "jti": "a1b2c3d4"

Public claims can be defined by the IANA JWT registry or using a collision-resistant name (e.g., include a URI). Private claims are custom agreements between parties.

Example payload with registered and private claims:

{
  "sub": "1234567890",
  "name": "John Doe",
  "iat": 1516239022,
  "exp": 1516242622,
  "scope": "read:profile"
}

3. Base64url Encoding

Both header and payload must be encoded using base64url. This variant of base64 is URL-safe:

  • + becomes -
  • / becomes _
  • Trailing padding = is removed.

The encoding process (in JavaScript) would be:

// Convert JSON string to UTF‑8 bytes, then to base64, then apply URL-safe replacements
const base64 = btoa(unescape(encodeURIComponent(jsonStr)));
const base64url = base64.replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');

For the example header, the base64url becomes: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.

4. Create the Signature

The signature is computed over the concatenation of the encoded header and payload (separated by a dot):

signatureInput = base64Url(header) + "." + base64Url(payload)

The signing algorithm depends on the alg field:

  • HS256 (HMAC-SHA256): HMACSHA256( signatureInput, secret ) – symmetric, same secret used to verify.
  • RS256 / ES256: Use private key for signing, public key for verification (asymmetric). Not supported in this browser tool for simplicity.
  • none: Signature is omitted. The token becomes header.payload. (trailing dot). Should never be used in production.

The resulting signature is also base64url‑encoded.

For HS256 with secret "mysecret" and the example header/payload, the signature base64url is SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c.

5. Assemble the Final Token

Combine the three parts with dots:

JWT = base64Url(header) + "." + base64Url(payload) + "." + base64Url(signature)

For the example:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

Algorithm Deep Dive

HS256 (HMAC with SHA-256) is the simplest signing method. It uses a single secret key for both signing and verification. The secret should be random and at least 256 bits long. Because the same key is shared, it must be kept confidential on both ends. HS256 is fast and suitable for server-to-server communication where the secret can be securely distributed.

RS256 (RSA with SHA-256) uses a private/public key pair. The signer holds the private key, while anyone can verify using the public key. This enables scenarios like OpenID Connect where identity providers sign tokens and resource servers verify without sharing secrets.

ES256 (ECDSA with SHA-256) provides similar security to RSA but with smaller signatures, making it attractive for constrained environments.

"none" algorithm should only be used for debugging. In 2015, a critical vulnerability (CVE-2015-9235) allowed attackers to change the algorithm to "none" and bypass signature verification. Always configure your JWT library to reject "none".

Step‑by‑Step Example (HS256)

Let's encode the following:

Header:  {"alg":"HS256","typ":"JWT"}
Payload: {"sub":"user42","iat":1672531200,"exp":1672534800}
Secret:  "topSecretKey"
  1. Encode header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  2. Encode payload: eyJzdWIiOiJ1c2VyNDIiLCJpYXQiOjE2NzI1MzEyMDAsImV4cCI6MTY3MjUzNDgwMH0
  3. Signature input: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyNDIiLCJpYXQiOjE2NzI1MzEyMDAsImV4cCI6MTY3MjUzNDgwMH0
  4. Compute HMAC-SHA256 with "topSecretKey": (output in hex, then base64url) → J8Hj5f1h... (example)
  5. Final token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyNDIiLCJpYXQiOjE2NzI1MzEyMDAsImV4cCI6MTY3MjUzNDgwMH0.8xH1K6J8y5m0wzF9jLq1pP2sR3tU4vW5xY6zA7bC8dE

Security Best Practices for JWT Encoding

  • Always sign your tokens. Never use "none" in production.
  • Use strong secrets for HS256. Generate a random string of at least 32 bytes (256 bits).
  • Keep secrets secure. Do not embed secrets in client-side code. For web apps, the signing should happen on the server.
  • Set short expiration times (exp). Minutes to hours, not days. Combine with refresh tokens if needed.
  • Include the audience (aud) and issuer (iss) claims to restrict token usage to specific services.
  • Validate the algorithm on the receiving side. Attackers may try to change the header to "none" or from RS256 to HS256 (key confusion attack). Always verify that the algorithm matches your expectation.
  • Do not store sensitive data in the payload. JWTs are only base64 encoded, not encrypted. Use JWE (JSON Web Encryption) for confidentiality.
  • Use the jti claim and maintain a blacklist if you need to revoke tokens before expiration.

Common Mistakes When Encoding JWTs

  • Malformed JSON: Trailing commas, missing quotes, or using single quotes will break parsing.
  • Mismatched alg and actual signing method: The header must reflect the algorithm used.
  • Weak secret (e.g., "secret"): Easily brute‑forced. Use a long random string.
  • Forgetting to remove base64 padding: The token must be base64url without = padding.
  • Encoding issues with Unicode: Always convert JSON strings to UTF‑8 before base64.
  • Using the wrong signature input: Some implementations incorrectly include the trailing dot. The correct input is headerBase64 + "." + payloadBase64.

JWT vs. Traditional Sessions

JWTs are stateless: all necessary information is inside the token. This scales well in distributed systems because the server does not need to store session state. However, revocation becomes harder. Sessions with server‑side storage make revocation trivial but may introduce a central point of failure. Choose based on your use case.

This guide provides over 1500 words of detailed instruction to help you master JWT encoding.