Base64 Is Not Encryption — Here's What It Actually Is
Every few months, someone posts a "hidden API key" in a public GitHub repo and later claims they thought encoding it in Base64 would protect it. It doesn't. Anyone can decode it in seconds. This confusion — treating encoding as a form of security — leads to real vulnerabilities. Let's clear it up.
What Base64 actually does
Base64 is a way to represent binary data using only printable ASCII characters. That's it. It has nothing to do with secrecy. There's no key, no algorithm that makes it hard to reverse, and no secret involved. Give anyone a Base64 string and they can decode it instantly — that's by design.
The 64 characters it uses are: A–Z (26), a–z (26), 0–9 (10), and + and / (2). Padding is handled with =.
The encoding process takes 3 bytes (24 bits) of input and produces 4 Base64 characters (24 bits ÷ 6 bits per character = 4). This is why Base64-encoded output is always about 33% larger than the original data.
Why Base64 exists at all
Most text-based protocols — email (SMTP), HTTP headers, URLs — were designed to handle ASCII text, not arbitrary binary data. When you need to send a binary file (an image, a PDF, a compiled executable) through one of these systems, you need to convert it into characters those systems won't mangle.
Base64 solves this. It converts any binary sequence into a predictable set of safe ASCII characters that survive transport through text-based systems. The receiver decodes it back to the original bytes.
Where you'll actually encounter it
HTTP Basic Authentication. When a client authenticates with a username and password using Basic Auth, the credentials are formatted as username:password and Base64-encoded, then sent in the Authorization header like this:
Authorization: Basic dXNlcjpwYXNzd29yZA==
That encoded string is not encrypted. Anyone who can see the HTTP header can decode it immediately. This is why Basic Auth must always be used over HTTPS — the TLS layer provides the actual protection.
JWT tokens. A JSON Web Token consists of three Base64url-encoded parts separated by dots. The header and payload are just Base64-encoded JSON. If you have a JWT, you can read the payload without any key. The signature part is what provides verification that the token hasn't been tampered with — but it doesn't hide the contents.
Email attachments (MIME). Email attachments are Base64-encoded in the message body so they can pass through SMTP servers that only handle text. When your email client "downloads" an attachment, it's decoding Base64.
Data URIs. To embed an image directly in HTML or CSS without a separate file request, you Base64-encode it and use it as a data URI:
background-image: url('data:image/png;base64,iVBORw0KGgo...');
This is legitimate and common for small icons and inline assets.
Standard Base64 vs URL-safe Base64
Standard Base64 uses + and /, which have special meaning in URLs (+ is a space in query strings, / is a path separator). Using standard Base64 in a URL will break things.
URL-safe Base64 (also called Base64url) replaces + with - and / with _. JWTs use Base64url for this reason. When decoding a JWT payload manually, you may need to convert from Base64url to standard Base64 first by swapping those characters back.
Common mistakes
Thinking it's encryption. It is not. If you need to protect data, use actual encryption (AES, RSA, TLS). Base64 is purely a transport/storage encoding.
Double-encoding. Taking a string that's already Base64, encoding it again, and wondering why the decoder gives unexpected output is a common debugging headache. When in doubt, try decoding once and inspecting the result before re-encoding.
Forgetting padding. Base64 output length must be a multiple of 4, padded with = characters. Some implementations strip padding, which can cause errors when decoding. If you get a "invalid Base64" error on something that looks mostly right, try adding = or == to the end.
Encoding entire files in browser-based tools. Base64 is about 33% larger than the original binary. Encoding a 10 MB file gives you a 13+ MB string. Most browser tools handle text input; for binary files you need a dedicated file-based encoder.
Quick reference: encoding by hand
Take the text hi:
- ASCII bytes:
104,105 - Binary:
01101000 01101001 - Grouped into 6-bit chunks:
011010 000110 1001xx(padded to 3 groups of 6) - Base64 characters:
a,G,k, and=for padding - Result:
aGk=
You don't need to do this by hand. But understanding the mechanics removes the mystery.
Base64 Encoder / Decoder — Instantly encode text to Base64 or decode Base64 strings. Runs entirely in your browser.
Open Tool