YamlBox

Web & encoding · 5 min read

Base64 decode and encode: for transport, not security

Base64 exists to move binary data through channels that only accept text. It maps every three bytes into four printable characters, which is why encoded output is about a third larger than the input and why a base64 decode is entirely reversible — with no key, because base64 is encoding, not encryption. Anyone can decode anything you encode, and any tool that suggests otherwise is lying to you.

Updated

The alphabet and the padding

The standard alphabet is `A–Z`, `a–z`, `0–9`, `+` and `/`, with `=` padding the final group when the input length is not a multiple of three. That padding is not decorative: it tells the decoder how many bytes the last group carries. Stripping it is common in URLs and works because decoders infer the length, but strict implementations will reject the unpadded form.

                "YamlBox"  →  WWFtbEJveA==
"YamlBo"   →  WWFtbEJv
              

base64url: the variant that ends up in tokens

URLs treat `+`, `/` and `=` as significant, so the base64url variant replaces them with `-` and `_` and often omits padding entirely. Every JSON Web Token uses this alphabet, which is why a JWT payload pasted into a strict Base64 decoder can fail on characters that look perfectly ordinary. If a string decodes to something near-but-not-quite readable, you are usually one alphabet swap away from the answer.

Where you meet it in practice

  • Data URIs — embedding small images and fonts directly in CSS or HTML as `data:image/png;base64,…`.
  • JSON Web Tokens — each of the three segments is base64url encoded.
  • HTTP Basic authentication — `Authorization: Basic` carries base64 of `user:password`, which is why it must always travel over TLS.
  • Email attachments — MIME has used base64 for binary parts since the 1980s.
  • APIs that cannot accept binary — image payloads and keys placed into text-only fields.

Why Base64 decode output looks like garbage

The classic failure is Unicode. JavaScript’s older `btoa` and `atob` operate on one byte per character, so a string containing `é`, `₹` or any emoji either throws or produces mojibake. The fix is to encode the UTF-8 bytes first — `TextEncoder` in the browser, `Buffer.from(str, "utf8")` in Node — and then base64 those. If a decode returns plausible-looking but wrong characters, the most likely cause is that the encoder never converted text to UTF-8 bytes at all.

Base64 provides no confidentiality or integrity. Treat an encoded secret exactly as you would the raw secret, because that is what it is.

Why decode locally

Basic-auth headers, tokens and data URIs all decode to credentials or private data, so pasting them into a server-side decoder is a disclosure. The YamlBox Base64 encoder/decoder works in the page with UTF-8 handling done correctly, supports both the standard and URL-safe alphabets, and functions offline.

Base64 Encoder / Decoder — frequently asked questions

Is Base64 encryption?

No. It is a reversible encoding with no key, so anyone can decode it. It exists so binary data can travel through text-only channels — never to protect data. Use TLS and real encryption such as AES-GCM for confidentiality.

How much larger is Base64 output?

Exactly one third larger, plus a little padding, because three bytes become four characters. That overhead is why base64 is used for small assets inline and avoided for large ones.

Why does a Base64 decode return strange characters?

Usually an encoding mismatch: the original text was not converted to UTF-8 bytes before encoding, or you are decoding base64url data with a standard decoder. Check for `-` and `_` characters, and confirm the source encoder used UTF-8.

Tools mentioned in this post

Browse all 19 tools →

Keep reading

All 19 posts →