Base64 is a transport encoding, not a secret
Base64 appears in security advice often enough that people assume it protects something. It does not. It is a way of writing binary data using characters that survive systems which only handle text.
By Enrique M. · 6 min read · Last reviewed 2026-10-18
What it does
Base64 maps every three bytes of binary data onto four printable characters from a 64-character alphabet. That expansion is why the output is a third larger than the input, and it is why a JPEG becomes a long line of text that can be pasted into a JSON body or an email header without corrupting anything.
The alphabet has two variants. The standard one uses `+` and `/`, and the URL-safe one uses `-` and `_` and usually drops the padding, which is what a JWT and a URL query parameter require.
- Standard: `A-Z a-z 0-9 + /` with `=` padding
- URL-safe: `A-Z a-z 0-9 - _` without padding
- The conversion is reversible by anyone, in one step, with no key.
Why it is not encryption
Encryption needs a key. Base64 has none, so anybody who can see the string can decode it. The decode is a single function call in every language, and the online version of it is a text box.
The base64 of a secret is not a secret. If a credential is base64-encoded in a configuration file, in a URL, in a log line or in a database column, it is a plaintext credential with extra characters. It has to be protected exactly like the plaintext would be, which usually means it should not be stored there at all.
// This is not protection.
const encoded = btoa(password);
// This is the same password.
console.log(atob(encoded)); The three cases where people reach for it by mistake
The first is hiding a password. The second is signing a payload, where the right tool is HMAC or a signature over the original bytes. The third is obfuscating an API key in a client-side application, where the key is readable by anyone with devtools open.
In the third case the key is in the bundle, whether it is base64, encrypted with a key that is also in the bundle, or split into pieces that are reassembled in the same file. The only real fix is for the secret to not be in the client at all.
Where Base64 is the right tool
Base64 is genuinely the right answer in several common situations, and reaching for it there is correct rather than naive. It is how binary data travels through a text-only channel, how a data URI embeds an image in a stylesheet, how an HTTP header carries an attachment, and how a JWT carries its payload in a URL-safe form.
In all of them, the point is transport rather than secrecy, and the security comes from somewhere else: TLS, a signature, or the fact that the content was never secret.
- Encoding binary in JSON, XML, a query string or an email header.
- Building a `data:` URI for an inline image or a font.
- Encoding an SMTP attachment or an HTTP header value.
- The payload and header of a JWT, where the signature is what provides integrity.
What to take away
- Base64 has no key, so anybody who can see it can decode it.
- A base64-encoded secret is a plaintext secret with extra characters.
- The output is a third larger than the input, which matters in a URL.
- Base64 is the right tool for moving binary through a text channel, and the wrong tool for hiding anything.