🧩 What Is the Structure of a JWT?

A JWT token is made up of three parts, separated by a dot (.):

[Header].[Payload].[Signature]
Header
Specifies the token type and algorithm
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
Payload
Contains the actual data — user ID, email, role
eyJ1c2VySWQiOjEyMywiZW1haWwiOiJ0ZXN0QGdtYWlsLmNvbSJ9
Signature
Ensures the token has not been tampered with
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

⚠️ Both the header and the payload are simply Base64-encoded. The signature is cryptographically signed — not the data itself.

🔤 What Is Base64 Encoding?

Base64 is an encoding format that converts binary or text data into a specific character set. It uses the following characters:

A-Z, a-z, 0-9, +, / (standard Base64) A-Z, a-z, 0-9, -, _ (Base64url — used in JWT)

This is a reversible process — meaning what has been encoded can be easily decoded. Here's proof:

Original JSON (Payload):

{ "userId": 123, "email": "test@gmail.com", "role": "admin" }

Base64 Encoded:

eyJ1c2VySWQiOjEyMywiZW1haWwiOiJ0ZXN0QGdtYWlsLmNvbSIsInJvbGUiOiJhZG1pbiJ9

Decoding it? Just one line of code:

// Node.js const decoded = Buffer.from( 'eyJ1c2VySWQiOjEyMywiZW1haWwiOiJ0ZXN0QGdtYWlsLmNvbSIsInJvbGUiOiJhZG1pbiJ9', 'base64' ).toString(); console.log(decoded); // Output: {"userId":123,"email":"test@gmail.com","role":"admin"}

🚨 See? No password, no key — just a simple function call and your entire payload is in front of you.

⚖️ Encoding vs Encryption — The Real Difference

This is where many developers get confused. Here is a clear comparison:

Property Encoding (Base64) Encryption (AES/RSA)
Purpose To transmit data in a compatible format To keep data secret
Reversible Yes — anyone can decode Yes — but only with the correct key
Key required No Yes — cannot be decrypted without it
Examples Base64, URL Encoding AES, RSA
Security None — provides no security Strong — data is protected

💡 Simply put: Encoding is like an open book that anyone can read. Encryption is like a locked box that only those with the right key can open.

🤔 So Why Does JWT Use Base64?

If Base64 isn't secure, why does JWT use it? There are several practical reasons:

1
URL-safe transmission JWT tokens are transmitted in HTTP headers, URL query parameters, and cookies. Raw JSON contains characters such as { } " : which can cause issues. Base64url encoding converts all of these into safe ASCII characters.
2
Compact format Base64-encoded strings are more compact than raw JSON and can be efficiently transmitted over the network.
3
Consistent format The JWT specification (RFC 7519) required a standard format that works consistently across all programming languages and platforms. Base64 is universally supported.
4
Easy debugging Since the payload can be easily decoded, developers can see what data the token contains during development and debugging.

🔒 Then How Is JWT Secure?

The security of JWT comes not from Base64, but from the signature.

How is the signature made?

HMAC-SHA256( base64url(Header) + "." + base64url(Payload), SECRET_KEY )

This means the header and payload are hashed using your secret key. This hash serves as the signature.

What happens if an attacker tries to modify the JWT's payload — for example, changing "role": "user" to "role": "admin"?

If the payload changes, the signature becomes invalid. When verifying the signature, the server detects that the token has been tampered with and rejects the request.

🛡️ Key point: An attacker can read the payload, but cannot modify it undetected. That is the security model of JWT.

Why not try it yourself? Enter any JWT token on jwt.io — you'll see the full contents of the header and payload without knowing the secret key. The secret key is required only to verify the signature, not to read the data. This is proof that a JWT is not encrypted.

What Should (and Should Not) Go in the JWT Payload?

Since anyone can decode the JWT payload, it should never contain sensitive information.

❌ Never Include
  • Passwords or password hashes
  • Credit card numbers
  • Bank account information
  • Private API keys
  • Social Security numbers
  • Any personally identifiable sensitive data
✅ Safe to Include
  • User ID (e.g., database _id)
  • User role (admin, user, moderator)
  • Email address (if privacy is not a concern)
  • Token expiry time (exp)
  • Issued at time (iat)

🔏 What If the Payload Also Needs to Be Encrypted?

If you also want to ensure the confidentiality of the payload — meaning that no one can read it — JWE (JSON Web Encryption) is used for this purpose.

JWE is a standard that fully encrypts JWTs. The payload is secured using either asymmetric or symmetric encryption.

💡 However, a standard JWT (JWS — JSON Web Signature) is sufficient for most applications. Just be sure not to include any sensitive data in the payload.

🔄 Base64url vs Base64 — What's the Difference?

JWT specifically uses Base64url, not regular Base64. There's a small but important difference:

Format Character Set Padding
Regular Base64 A-Z, a-z, 0-9, +, / = (used)
Base64url (JWT) A-Z, a-z, 0-9, -, _ = (removed)

In Base64url: + is replaced with -, / is replaced with _, and = padding is removed. This is because + and / have special meaning in URLs and can create problems.

Who Is Actually in Charge of JWT Security?

The security layers in JWT work like this:

1
Base64URL encoding For secure data transmission — not to guarantee security.
2
Signature (HMAC/RSA) To ensure data integrity — tokens cannot be tampered with.
3
HTTPS Tokens cannot be intercepted on the network.
4
Strong secret key To protect signatures from brute-force attacks.
5
Token expiration Stolen tokens remain valid only for a limited time.

🔑 The most important layer is a secure secret key. If your secret key is weak, an attacker can guess it and create valid signatures. Generate a strong, cryptographically secure key instantly at jwtsecretkeygenerator.com.

Frequently Asked Questions

Is JWT Base64 encoded or encrypted?

JWT uses Base64url encoding — not encryption. The header and payload are simply encoded, which means anyone can decode them without any key. The security of JWT comes from its cryptographic signature, not from the encoding.

Can anyone read the JWT payload?

Yes. The JWT payload is Base64url-encoded and can be decoded by anyone without any key. You can paste any JWT into jwt.io and read the full contents of the header and payload instantly. This is why you should never store sensitive data like passwords or credit card numbers in the JWT payload.

What is the difference between Base64 and Base64url?

Regular Base64 uses + and / characters and = padding. Base64url (used in JWT) replaces + with -, replaces / with _, and removes = padding. This makes the string safe for use in URLs and HTTP headers, where + and / have special meaning.

What is JWE and when should I use it?

JWE (JSON Web Encryption) is a standard that fully encrypts the JWT payload so that no one can read it without the correct key. You should use JWE when the payload itself contains sensitive data that must be kept confidential. For most applications, a standard JWT (JWS) with a strong secret key and no sensitive data in the payload is sufficient.

Conclusion

Base64 encoding in a JWT is not intended to provide security, but rather to make the data URL-compatible and transferable. Anyone can decode the payload of a JWT — it is not encrypted. The actual security of a JWT relies on its signature, which cannot be verified or created without the secret key.

🔐 To generate a strong and secure JWT secret key, visit jwtsecretkeygenerator.com. There, you can obtain a cryptographically secure key with just one click. Security starts with a strong key — never underestimate this.