What Base64 Is (and Why It Isn't Encryption)

By Junaid Aslam. 3 min read. Updated .

Base64 shows up everywhere: email attachments, data URLs, API tokens, the login header your browser sends. It looks scrambled, so people assume it's protecting something. It isn't. Base64 is a way to write binary data using only plain text characters.

Why Base64 exists

A lot of old systems were built to carry text, not raw bytes. Email is the classic example. If you try to push an image through a text-only channel, some bytes get changed or treated as control characters, and the file arrives broken. Base64 fixes that by turning any bytes into 64 safe characters: A-Z, a-z, 0-9, + and /.

How it works, in one paragraph

Base64 takes your data three bytes at a time. Three bytes is 24 bits. It slices those 24 bits into four groups of 6 bits, and each 6-bit group (a number from 0 to 63) picks one character from the alphabet. So every 3 bytes in becomes 4 characters out. If the input doesn't divide evenly by three, the output gets one or two = characters at the end as padding.

Input textBase64 output
HelloSGVsbG8=
Hello WorldSGVsbG8gV29ybGQ=
user:passdXNlcjpwYXNz

Paste any of those outputs into the Base64 tool and decode them. You'll get the original text straight back. No key, no password.

Why it's not encryption

Encryption needs a secret key. Without the key, the data stays unreadable. Base64 has no key. Anyone who sees the string can decode it in a second, with a browser tool, a terminal command, or a line of code.

Developers sometimes stash passwords or API keys in Base64 and call them 'encoded' or 'obfuscated', then those values end up in a public repo or a config file. Treat any Base64 string as plain text with a costume on.

HTTP Basic authentication sends username:password as Base64. That's exactly why it must only travel over HTTPS. The Base64 layer protects nothing. TLS does the protecting.

The size cost

Since 3 bytes become 4 characters, Base64 output is about 33% bigger than the original. A 300 KB image becomes roughly 400 KB of text. That's fine for a tiny icon inlined in CSS. It's a bad trade for a large photo, because you lose browser caching for that image and inflate your page size.

Standard vs URL-safe Base64

Standard Base64 uses + and /. Both have special meaning in URLs. A + can be read as a space and a / splits a path. The URL-safe variant (called base64url in RFC 4648) swaps them for - and _, and often drops the = padding.

The three bytes FB FF FE come out as +//+ in standard Base64 and -__- in the URL-safe form. If you paste a standard string into a URL and it breaks, this is usually why. You can also percent-encode it instead.

Where you'll meet Base64

  • Data URIs: data:image/png;base64,iVBOR... lets you embed a small image directly in HTML or CSS.
  • JWTs: the three dot-separated parts of a JSON Web Token are base64url. The header {"alg":"HS256","typ":"JWT"} becomes eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9. Anyone can read the payload of a JWT. The signature is what makes it trustworthy, not the encoding.
  • Email (MIME): attachments are Base64 encoded so they survive text-based mail systems.
  • Basic auth headers: Authorization: Basic dXNlcjpwYXNz.
  • Config and secrets in Kubernetes: values in a Secret object are Base64. Again, that's encoding, not protection.

A common bug: Unicode text

In browser JavaScript, the built-in btoa() function only handles characters up to code point 255. Give it an emoji or a Chinese character and it throws an error. The fix is to convert your string to UTF-8 bytes first (with TextEncoder), then Base64 those bytes. The Base64 tool handles this for you, so accented and non-Latin text round-trips correctly.

When to use it, and when not to

  • Use it to move binary data through a text-only channel (JSON fields, headers, email).
  • Use it for tiny inline assets where saving an HTTP request matters more than the 33% overhead.
  • Don't use it to hide anything. If you need secrecy, encrypt with a real algorithm such as AES-GCM, and manage the key properly.
  • Don't use it for large files when you can send the bytes directly instead.

Try it yourself

More guides