Base64 Is Not Encryption: What Every Developer Should Know
If you've ever seen a Base64-encoded string in a log file, an API response, or a credential file, you've probably wondered whether it's safe. The short answer: no. Base64 is an encoding, not encryption. Anyone — including the person sitting next to you at a coffee shop — can decode a Base64 string in under a second, without a key, without a password, without any secret at all.
This post explains what Base64 actually is, what it's good for, what it's absolutely not good for, and what to use instead when you need real security.
What Base64 actually is
Base64 is a binary-to-text encoding scheme that represents arbitrary bytes using 64 printable ASCII characters: A–Z, a–z, 0–9, and two symbols (typically + and /). Every 3 bytes of input produce 4 characters of output. It's defined in RFC 4648.
The purpose of Base64 is to let you transmit binary data through channels that only handle text: HTTP headers, URL query strings, JSON payloads, email bodies, and XML attributes. Without Base64 (or similar encodings), you couldn't attach an image to a JSON document or embed a PNG icon in a CSS file.
Base64 is to binary data what URL encoding is to special characters in URLs — a safe-for-transport escape format, not a security measure.
Why it feels like encryption (but isn't)
Base64-encoded strings look random. They contain letters and numbers in patterns that don't resemble natural language. It's easy to look at one and assume the content must be protected somehow.
But the protection is cosmetic. The Base64 alphabet is public. The encoding algorithm is public. Every programming language and operating system ships with a built-in decoder. Anyone who sees a Base64 string can paste it into a decoder — or any browser's developer console — and read the original content immediately.
// In any browser console, right now:
atob("SGVsbG8gd29ybGQ="); // → "Hello world"Where Base64 IS the right choice
Base64 is genuinely useful when your problem is transport, not secrecy:
- Embedding images as data URIs in HTML or CSS (data:image/png;base64,…)
- Sending binary files as part of a JSON API request body
- HTTP Basic Authentication (though this should only ever be used over HTTPS, precisely because Base64 is not secret)
- Encoding cryptographic keys or signatures for storage in text files
- Representing random bytes as a copyable string (session tokens, nonces)
In all of these cases, Base64 is doing exactly what it's designed to do: turning bytes into something that survives a text-only channel.
Where Base64 is NOT the right choice
Never use Base64 as a way to "protect" data:
- Do not Base64-encode passwords thinking it hides them. It doesn't.
- Do not Base64-encode API secrets before committing them to a repo. Git log is public.
- Do not Base64-encode session data and trust the client not to read it. It will be read.
- Do not Base64-encode user PII in a URL query parameter. It's still visible.
- Do not use Base64 in place of JWT signing to "verify" payloads. There's no verification without a signature.
If you need actual secrecy, you need encryption: a process that requires a key to reverse. If you need to verify that a payload hasn't been tampered with, you need a signature (HMAC or asymmetric). Base64 provides neither.
What to use instead
For secrecy: AES encryption
AES-256-GCM is the modern standard for symmetric encryption. It provides both confidentiality (the data can't be read without the key) and authenticity (the data can't be tampered with without detection). Every major language has a well-audited implementation.
For integrity: HMAC
HMAC-SHA256 (or HMAC-SHA512) is the standard for proving that a message was produced by someone who knows a shared secret. GitHub, Stripe, and Slack all use HMAC to sign webhook payloads so receivers can verify them.
For passwords: bcrypt, scrypt, or Argon2
Passwords should never be encrypted (which is reversible) — they should be hashed with a slow, salted, memory-hard algorithm designed for the purpose. bcrypt, scrypt, and Argon2 are the three widely-accepted choices in 2026.
For tokens: JWT with a signing key
If you need to send a payload to a client and later verify it hasn't been modified, use a signed JWT. The token is Base64-encoded (so humans can see the claims), but it includes a cryptographic signature that proves the contents are authentic.
The TL;DR
Base64 is an encoding designed to move binary data through text-only channels. It does that job well and is used everywhere in modern web development. It provides zero secrecy. If you need secrecy, use AES. If you need integrity, use HMAC. If you see Base64 being used as a "security layer" in a codebase, it's a sign that something is going to break.
Try the Base64 Encoder / Decoder