Base64 Is Not Encryption: What It Is For and Where It Hurts You
Base64 (RFC 4648) exists to move binary data through channels that only handle text safely — JSON bodies, HTTP headers, XML, email. It maps every 3 bytes of input onto 4 characters from a 64-symbol alphabet: A–Z, a–z, 0–9, + and /. When the input length is not a multiple of 3, the last group is padded with one or two = signs — which is why Base64 strings so often end in = or ==. The output is about 33% larger than the input: a 300 KB image becomes roughly 400 KB of text.
Legitimate uses
- Email attachments: MIME wraps binary files in Base64 so mail servers that assume text do not mangle them.
- Data URIs: small fonts and images embedded directly in CSS or HTML (
data:image/png;base64,...) to save HTTP requests. - HTTP Basic authentication: the
Authorization: Basicheader carries Base64 of user and password — encoding only, which is exactly why it must always run over HTTPS. - Bearer tokens and JWTs: the parts of a JWT are Base64URL segments.
The dangerous misunderstanding
"We encoded it, so it is safe" is false. Decoding needs no key, no tool beyond a one-liner, and no time: any Base64 string reverts in seconds. If data is confidential it needs encryption, for example AES-GCM with a proper key; if it is a password, it needs a slow salted hash. Base64 is packaging, not a lock — a cardboard box, not a safe. Writing credentials into configuration as Base64 protects nothing and gives a false sense of diligence.
Why the 4/3 ratio exists
The alphabet has 64 symbols, and 2^64 equals 2^48 times 2^16 — more precisely, 4 Base64 characters carry 24 bits, exactly 3 bytes. Encoding takes 3 bytes at a time, so input whose length is not a multiple of 3 leaves a remainder: one leftover byte becomes two characters plus ==, two leftover bytes become three characters plus =. You can verify any string in seconds from a terminal:
echo "SGVsbG8sIHdvcmxk" | base64 -d Hello, world
That is the entire "decryption" effort — one standard command, no key. Decoders also typically ignore whitespace and line breaks, which is why a Base64 blob pasted from an email with wrapped lines still decodes cleanly.
Variants worth knowing
- Base64URL: swaps
+and/for-and_so tokens survive in URLs and cookie values without percent-encoding. JWTs always use this variant. - Without padding: some protocols strip the trailing
=; decoders usually accept both forms. - Line wrapping: MIME inserts line breaks every 76 characters; JSON APIs expect one continuous string.
A quick test for any string you suspect is Base64: does its length divide evenly by 4? Does it contain only the 64 symbols plus padding? If yes, it decodes — and you should assume anyone can read it. The WhoDNS Base64 tool encodes and decodes both standard and URL-safe variants instantly, so you can verify what a header, token or data URI actually contains before you trust it.
🔗 Related tool: Convert text with the Base64 tool