Code Beautifier
Encoding & Text

Base64 is not encryption: what it actually does

Base64 is an encoding, not a cipher. What it's for, why it makes data 33% bigger, when to use it, and what to use instead when you actually need secrecy.

Base64 shows up in a lot of places that feel security-adjacent: auth headers, JWTs, API keys, config files, certificates. That proximity leads to a persistent misunderstanding, which occasionally becomes a real incident.

Base64 is an encoding, not encryption. It provides no secrecy whatsoever. Anyone can reverse it instantly, without a key, because there is no key. Reversing it is the algorithm.

What it actually does

Base64 represents binary data using 64 printable ASCII characters: A–Z, a–z, 0–9, +, and /, with = for padding.

It exists because a lot of systems were built to carry text, not arbitrary bytes. Email bodies, URLs, HTTP headers, XML and JSON string values, HTML attributes. Send raw binary through those and something will mangle it, interpret a byte as a control character, or drop it. Base64 makes bytes survive the trip.

The mechanism is straightforward: take 3 bytes (24 bits), split into 4 groups of 6 bits, map each group to one of 64 characters. Since 3 input bytes become 4 output characters, the result is about 33% larger than the input. That is the cost, and it is the reason you do not Base64 everything by default.

Why "it looks encrypted" is a trap

YWRtaW46c3VwZXJzZWNyZXQ= looks like ciphertext to the naked eye. It decodes to admin:supersecret.

That visual opacity is the whole problem. Real cases this causes:

  • Credentials in config, Base64-encoded, committed to a repo, on the theory that they were obscured. They were not.
  • HTTP Basic Auth, which is literally base64(username:password) in a header. This is why Basic Auth without TLS is equivalent to sending a plaintext password.
  • JWT payloads, which are Base64url-encoded and fully readable by anyone holding the token. The signature prevents tampering, not reading.
  • "Encoded" API responses that a developer assumed were protected.

If an attacker can read the encoded value, they can read the original. There is no work factor, no key, nothing to break.

Base64 vs. encryption vs. hashing

These three get conflated constantly, and the distinction is worth being precise about:

Reversible? Needs a key? For
Encoding (Base64) Yes, by anyone No Safe transport of bytes through text channels
Encryption (AES) Yes, with the key Yes Confidentiality
Hashing (SHA-256) No No Integrity, fingerprints, password storage (with a salt and a slow KDF)

Wanting something unreadable means encryption. Wanting to verify something has not changed, or to store a password, means hashing, and for passwords specifically a purpose-built slow hash such as bcrypt or Argon2 rather than a raw SHA.

When Base64 is the right call

It has real, correct uses:

  • Binary in JSON or XML, since neither can hold raw bytes in a string.
  • Data URIs, embedding a small image directly in CSS or HTML to avoid a request. Worth it for tiny assets; the 33% growth stops being worth it quickly.
  • Email attachments, via MIME, which is the original motivation.
  • PEM certificates, which are Base64-wrapped DER with header and footer lines.
  • Binary-ish values in HTTP headers, which must be ASCII.

The URL-safe variant

Standard Base64 uses + and /, which both have meaning in URLs, and = padding, which is awkward in query strings.

Base64url swaps +- and /_, and usually drops the padding. This is what JWTs use, which is why token segments contain - and _ and rarely end in =. Decoding a JWT segment with a strict standard-Base64 decoder can fail for exactly this reason.

Try it

The fastest way to internalize that this is not encryption is to round-trip something yourself. The Base64 encoder/decoder runs entirely in your browser, so you can safely paste something real: encode a password, look at the output, decode it back, and note that at no point were you asked for a key.

If you need an actual one-way transformation, the hash generator does SHA-256 and friends. If you need to store a password, use bcrypt.