🧩 What Is the Structure of a JWT?
A JWT token is made up of three parts, separated by a dot (.):
[Header].[Payload].[Signature]
⚠️ 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:
{ } " : which can cause issues. Base64url encoding converts all of these into safe ASCII characters.
🔒 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.
- Passwords or password hashes
- Credit card numbers
- Bank account information
- Private API keys
- Social Security numbers
- Any personally identifiable sensitive data
- 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:
🔑 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.