The short version
Base64 is a way of writing any sequence of bytes using 64 safe characters (A–Z, a–z, 0–9, +, /). It exists so that binary data — an image, a PDF, a key — can travel through systems that only handle text: e-mail bodies, JSON strings, URLs, HTML attributes. It is encoding, not encryption: there is no key, and decoding it is a single function call available in every language and every browser’s developer console. A password stored “in Base64” is stored in plain text with extra steps.
Why it exists
E-mail was designed in the 1970s for 7-bit ASCII. When attachments arrived (MIME, 1992), the bytes of a JPEG — which use all 256 values, including ones that mean “end of line” or “end of message” to a mail server — had to be disguised as harmless text. Base64 was the answer: take three bytes (24 bits), split them into four 6-bit groups, map each group to one of 64 characters. Every 3 bytes become 4 characters, which is the famous 33 % overhead: a 3 MB attachment is a 4 MB e-mail, and that is why a “25 MB” mail limit fits an 18 MB file.
The same trick appears wherever text is the only channel: embedding a small image directly in a web page (data:image/png;base64,…), putting a binary token in an HTTP header (Authorization: Basic …), carrying certificates and keys in PEM files, and stuffing a byte array into a JSON field.
The variants that trip people up
- Standard vs URL-safe. Standard Base64 uses
+and/, both of which mean something in a URL. The URL-safe alphabet (RFC 4648 §5) swaps them for-and_. A token from one that is decoded as the other fails on those two characters. JWTs use the URL-safe form. - Padding. Output length is always a multiple of four, padded with
=. Some producers strip the padding (JWTs again); some decoders demand it. If a decode fails on an otherwise valid string, try adding=until the length divides by four. - Line wrapping. MIME wraps at 76 characters; PEM at 64. Decoders generally ignore whitespace, but not all do.
- Text encoding underneath. Base64 encodes bytes. To Base64 a string you first turn it into bytes, and the choice of UTF-8 vs UTF-16 vs Latin-1 changes the result. The classic JavaScript bug —
btoa("é")throwing — is exactly this:btoaonly accepts Latin-1. Encode to UTF-8 bytes first.
The Base64 tool handles both alphabets, padding, wrapping and UTF-8, and decodes to either text or a downloadable file, so a data: URL or an e-mail attachment can be turned back into the original in the browser.
Encoding, hashing, encrypting
These three words are used interchangeably in casual writing and mean completely different things.
| Reversible? | Needs a key? | Purpose | |
|---|---|---|---|
| Encoding (Base64, hex, URL-encoding) | Yes, by anyone | No | Make data fit a channel |
| Hashing (SHA-256, MD5) | No | No | Fingerprint data; verify it was not changed |
| Encryption (AES, RSA) | Yes, with the key | Yes | Keep data secret from anyone without the key |
A hash of a file lets you check that a download matches what the publisher put up — Hash computes MD5, SHA-1 and SHA-256/384/512 in the browser and compares against a pasted checksum. It does not hide anything: the file is still the file. Encryption is the only one of the three that provides secrecy, and it is only as strong as the key — which is where a properly random password comes in.
If you were about to Base64 a secret
Don’t. Specifically:
- Configuration files with Base64 passwords (a common pattern in older Java and .NET apps) are plain-text passwords to anyone who opens the file.
- “Obfuscated” API keys in front-end JavaScript are visible in the network tab, Base64 or not.
- Basic authentication over plain HTTP sends the username and password Base64-encoded, which is to say in the clear. It is acceptable only inside HTTPS, where the transport does the encrypting.
If data must be stored or sent and stay secret, encrypt it with a real cipher (AES-256-GCM through the platform’s crypto library), and then, if it has to travel through a text channel, Base64 the ciphertext. Encoding after encryption is fine. Encoding instead of encryption is the mistake.