Z
Zynocode

JWT Structure Explained: Header, Payload, Signature & Security Rules

Prashant Sharma· Founder & Technology StrategistPublished 24 October 2026 7 min read
A JWT split into header, payload and signature, with the signature computed as HMAC-SHA256 of header and payload with a secret
Quick Answer

A JSON Web Token (JWT) consists of three base64url-encoded components separated by dots: header, payload, and signature (RFC 7519, RFC 7515). The header specifies cryptographic algorithms, the payload stores claims, and the signature verifies integrity. Decoding a JWT reveals claims client-side but does not prove authenticity; server verification is strictly required.

JSON Web Tokens (JWT) are the foundation of modern distributed identity, OAuth 2.0 authorization, and stateless microservice authentication. Whether you are implementing Single Sign-On (SSO) with OpenID Connect or issuing short-lived API bearer tokens, tokens pass through HTTP headers, cookies, and mobile app storage millions of times per second.

Yet despite their widespread adoption, tokens remain widely misunderstood. Developers frequently confuse Base64Url encoding with encryption, fail to validate standard time claims, or expose applications to critical authentication bypasses. Understanding the precise three-part architecture of a JWT allows software engineers to build robust, secure authentication systems. You can decode and inspect tokens instantly using our client-side JWT Decoder, convert raw byte streams with our Base64 Encoder & Decoder, or verify cryptographic hash digests with our Hash Generator.

What Standards Define the JSON Web Token Architecture?

The architecture of a JSON Web Token is defined by four core specifications published by the Internet Engineering Task Force (IETF):

  • [RFC 7519: JSON Web Token (JWT)](https://datatracker.ietf.org/doc/html/rfc7519): Defines the compact, URL-safe container format for representing claims to be transferred between two parties as a JSON object.
  • [RFC 7515: JSON Web Signature (JWS)](https://datatracker.ietf.org/doc/html/rfc7515): Specifies the cryptographic signing mechanism, including the JWS Compact Serialization format that concatenates header, payload, and signature with periods (.).
  • [RFC 7518: JSON Web Algorithms (JWA)](https://datatracker.ietf.org/doc/html/rfc7518): Enumerates the cryptographic algorithms permitted for signing, encryption, and key agreement, including HMAC, RSA, and ECDSA suites.
  • [RFC 8725: JSON Web Token Best Current Practices](https://datatracker.ietf.org/doc/html/rfc8725): Details mandatory security rules, covering algorithm validation, claim verification, and mitigations against common token attacks.

Together, these standards define how tokens are structured, transmitted, and cryptographically verified.

The guide's HS256 token split into its header, payload and signature, with the header and payload decoded

How Does Base64Url Encoding Work in a JWT?

Every compact JWT is formatted as a single string containing three base64url-encoded segments separated by periods:

<Base64Url-Header>.<Base64Url-Payload>.<Base64Url-Signature>

Standard Base64 encoding represents binary data using 64 ASCII characters (A-Z, a-z, 0-9, +, and /), appending one or two equals signs (=) for padding. However, +, /, and = have special syntactical meanings in web URLs, query parameters, and HTTP header values.

Under RFC 7515 Section 2 and RFC 4648 Section 5, JWT mandates Base64Url encoding, which modifies standard Base64 with two rules:

  1. URL-Safe Alphabet: Replace the plus sign (+) with a hyphen (-), and replace the forward slash (/) with an underscore (_).
  2. Omit Padding: Strip all trailing equals sign padding characters (=). Parsers reconstruct required padding based on string length modulo 4 during decoding.

Because base64url is a reversible encoding scheme rather than an encryption cipher, any client or intermediate proxy can decode a JWT payload into plain text without possessing a secret key. Learn more about character translation in our guide to what is base64 encoding.

What Is Inside the JWT Header?

The JOSE (JSON Object Signing and Encryption) header is a JSON dictionary containing cryptographic metadata that instructs the verifier how to validate the token.

A standard header contains two primary parameters:

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

Key Header Claims:

  • `alg` (Algorithm): Mandatory parameter specifying the cryptographic signing algorithm defined in RFC 7518. Common values include HS256 (HMAC with SHA-256), RS256 (RSA signature with SHA-256), and ES256 (ECDSA with P-256 curve and SHA-256).
  • `typ` (Type): Optional parameter declaring the media type of the token. RFC 7519 Section 5.1 recommends the explicit value JWT. RFC 8725 Section 3.11 recommends explicit typing (e.g., application/at+jwt for access tokens) to prevent cross-token substitution attacks.
  • `kid` (Key ID): An optional hint indicating which specific key from a JSON Web Key Set (JWKS) was used to sign the token, enabling seamless key rotation.

What Are the Registered Payload Claims in RFC 7519?

The second segment of a JWT is the payload, commonly referred to as the claims set. A claim is a statement about an entity (typically the authenticated user) and additional operational metadata.

RFC 7519 Section 4.1 reserves seven official registered claim names. While none are strictly mandatory across all protocols, production authentication systems rely on them for access control:

ClaimFull NameSpecification PurposeExample Value
issIssuerIdentifies the principal identity provider that issued the token"https://labs.zynocode.com"
subSubjectIdentifies the authenticated subject / unique user identifier"usr_zynocode_dev_9821"
audAudienceIdentifies the intended recipients or backend API resource server"zynocode-api"
expExpiration TimeUnix timestamp (seconds) identifying when the token expires1774003600
nbfNot BeforeUnix timestamp (seconds) before which the token must not be accepted1774000000
iatIssued AtUnix timestamp (seconds) recording when the JWT was generated1774000000
jtiJWT IDUnique identifier providing a one-time token nonce to prevent replay attacks (commonly generated using UUID v4 or UUID v7)"01a16d90-3f7c-7000-a261-a3493bb39c4a"

In addition to registered claims, applications include public claims (such as standard OpenID Connect attributes like name and email) and private claims tailored to internal business logic (such as roles or org_id). To ensure payload data conforms to strict syntax rules, review our guide on JSON formatting best practices.

How Is the Cryptographic Signature Computed?

The third segment of a JWT provides cryptographic integrity and authenticity. Without a valid signature, an adversary could alter the payload (such as elevating a user role to administrator) without detection.

Under RFC 7515 Section 5.1, the signature is computed over the JWS Signing Input, which is formed by concatenating the encoded header, a period, and the encoded payload:

signingInput = ASCII(base64url(header) + "." + base64url(payload))

The signing algorithm specified in the alg header parameter is then applied to signingInput using the issuer's private key or shared secret:

signature = base64url(HMAC_SHA256(signingInput, secret))

The resulting binary digest is base64url encoded and appended to the token as the third element. When a backend server receives the token, it recalculates the expected signature over the received header and payload. If the recomputed digest matches the signature segment in constant time, the server confirms that the token originated from an authorized issuer and was not tampered with in transit.

What Is the Worked HS256 Example and Recomputation Test?

To see this process end-to-end, examine the following worked example constructed using Node.js standard crypto module.

Security Warning: The secret below is a public throwaway string printed solely for this educational test vector. Never reuse example secrets in production environments.

1. Example Configuration

  • Algorithm: HS256 (HMAC using SHA-256)
  • Secret Key: zynocode-dev-secret-do-not-use-in-production-782910485

2. Header and Payload Objects

// Decoded Header:
{
  "alg": "HS256",
  "typ": "JWT"
}

// Decoded Payload:
{
  "sub": "usr_zynocode_dev_9821",
  "name": "Dev Tester",
  "iss": "https://labs.zynocode.com",
  "aud": "zynocode-api",
  "iat": 1774000000,
  "nbf": 1774000000,
  "exp": 1774003600
}

3. Base64Url Serialized Segments

  • Encoded Header: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • Encoded Payload: eyJzdWIiOiJ1c3Jfenlub2NvZGVfZGV2Xzk4MjEiLCJuYW1lIjoiRGV2IFRlc3RlciIsImlzcyI6Imh0dHBzOi8vbGFicy56eW5vY29kZS5jb20iLCJhdWQiOiJ6eW5vY29kZS1hcGkiLCJpYXQiOjE3NzQwMDAwMDAsIm5iZiI6MTc3NDAwMDAwMCwiZXhwIjoxNzc0MDAzNjAwfQ
  • Signing Input: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3Jfenlub2NvZGVfZGV2Xzk4MjEiLCJuYW1lIjoiRGV2IFRlc3RlciIsImlzcyI6Imh0dHBzOi8vbGFicy56eW5vY29kZS5jb20iLCJhdWQiOiJ6eW5vY29kZS1hcGkiLCJpYXQiOjE3NzQwMDAwMDAsIm5iZiI6MTc3NDAwMDAwMCwiZXhwIjoxNzc0MDAzNjAwfQ
  • Computed Signature: XUnqvp0qEcUk0a1FyOmS6OE7P0LWfcCaSOJTX-mhSrc

4. Complete Canonical Token

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c3Jfenlub2NvZGVfZGV2Xzk4MjEiLCJuYW1lIjoiRGV2IFRlc3RlciIsImlzcyI6Imh0dHBzOi8vbGFicy56eW5vY29kZS5jb20iLCJhdWQiOiJ6eW5vY29kZS1hcGkiLCJpYXQiOjE3NzQwMDAwMDAsIm5iZiI6MTc3NDAwMDAwMCwiZXhwIjoxNzc0MDAzNjAwfQ.XUnqvp0qEcUk0a1FyOmS6OE7P0LWfcCaSOJTX-mhSrc

In our automated testing suite, re-running crypto.createHmac('sha256', secret).update(signingInput).digest() confirms an exact match with the token signature above.

Why Is Decoding Never Equivalent to Verifying?

The single most critical security principle in token handling is that decoding a JWT is not verifying a JWT.

Because Base64Url is completely reversible, anyone can take a valid token, unpack the payload JSON, change "sub": "user_123" to "sub": "admin_master", and re-encode the string. The resulting token looks completely valid to any parser that only decodes the structure.

If your backend code extracts user identities from token payloads without executing cryptographic signature checks against trusted keys, an attacker can impersonate any account at will.

Tool Transparency Notice: The Zynocode Labs online JWT Decoder operates strictly as a debugging utility. As clearly stated in the application interface: "We never verify or transmit your signatures." Our tool parses Base64Url strings locally inside your browser sandbox to display headers, payload claims, and human-readable timestamp conversions. It does not possess your private signing keys and never validates cryptographic signatures.

What Are the Critical Security Pitfalls in RFC 8725?

RFC 8725: JSON Web Token Best Current Practices documents real-world vulnerabilities uncovered across enterprise authentication frameworks. When developing or reviewing token verification logic, ensure your architecture enforces these mitigations:

1. Reject the "alg: none" Vulnerability (RFC 8725 Section 2.1)

RFC 7518 permits an unsecured algorithm identifier designated as "none", intended for testing or tokens whose security is handled by a transport envelope like TLS. Early JWT libraries contained a severe flaw: if an attacker submitted a token with "alg": "none" and an empty signature, the library treated the token as validly signed. RFC 8725 Section 2.1 requires libraries to strictly reject "none" unless the application explicitly configures unsecured contexts.

2. Prevent Algorithm Confusion / Key Confusion (RFC 8725 Section 2.1)

In asymmetric architectures (e.g., RS256), the identity server signs tokens with a private RSA key, while relying APIs verify tokens using the public RSA key. In an algorithm confusion attack, an attacker alters the header to specify symmetric HS256, re-signing the forged payload using the server's public key file text as the HMAC secret key. If the verification library accepts any algorithm specified in the header, it uses the public key string to verify the HMAC and grants access. RFC 8725 requires applications to lock verification algorithms on the server rather than trusting the token's alg header.

3. Strictly Validate Audience and Issuer (RFC 8725 Section 2.2)

Verifiers must confirm that iss matches the exact authorized authorization server domain and that aud matches the receiving service's registered identifier. Failing to validate aud allows a token issued for a low-privilege service to be replayed against a high-privilege service.

4. Enforce Expiration and Clock Skew Rules (RFC 8725 Section 2.6)

Verifiers must reject tokens where the current time exceeds exp or precedes nbf. When networks experience slight server clock drift, RFC 8725 recommends allowing a small clock skew tolerance of no more than a few minutes (typically 30 to 60 seconds).

Frequently asked questions

What are the three parts of a JSON Web Token?+

A JSON Web Token consists of three distinct segments separated by periods: the JOSE header (identifying the signing algorithm and token type), the payload claims set (containing user and authorization metadata), and the cryptographic signature (validating integrity).

Is a decoded JWT encrypted or private?+

No. Standard JWS tokens defined under RFC 7519 are signed, not encrypted. The header and payload are simply base64url encoded. Anyone who inspects the token can read every payload claim in plain text within milliseconds.

Why is decoding a JWT not equivalent to verifying a JWT?+

Decoding merely translates base64url characters into human-readable JSON without validating the cryptographic signature. An attacker can alter any payload claim and re-encode the string; only cryptographic verification against a trusted secret or public key proves authenticity.

What is the difference between HS256 and RS256 signing algorithms?+

HS256 uses a symmetric HMAC secret shared between the token issuer and verifier. RS256 uses asymmetric cryptography, where the authorization server signs tokens with a private RSA key and clients or API gateways verify them using a public key.

What is the algorithm confusion vulnerability described in RFC 8725?+

Algorithm confusion occurs when a verification server expecting an asymmetric signature (like RS256) blindly accepts an HMAC algorithm (like HS256) and verifies the token using the server's public RSA key string as the HMAC shared secret.

Prashant Sharma

Prashant Sharma · Founder & Technology Strategist

Prashant Sharma is the founder of Zynocode IT Solutions, specializing in web development, SEO tooling and generative AI workflows.

All guides