Base64 Is Not Encryption: What Developers Get Wrong

Updated · by the My Gadgets team

Base64 is an encoding, not encryption: it has no key, and anyone can turn it back into the original in one step. It exists to carry binary data through systems that only handle text, not to keep anything secret. Yet Base64 strings regularly guard passwords, API keys and personal data in configuration files, URLs, tokens and logs, because they look scrambled. This article explains the difference between encoding, encryption and hashing, shows the places the confusion causes real leaks, and what to use instead.

What does Base64 actually do?

Base64 rewrites any data using 64 safe characters: A–Z, a–z, 0–9, + and /, with = as padding. Every 3 bytes of input become 4 characters of output, so the result is about a third larger than the original.

admin:hunter2   →   YWRtaW46aHVudGVyMg==

That is the whole transformation. There is no secret involved: the alphabet is public, the rules are in a standard (RFC 4648), and every programming language and browser can reverse it. Paste the string into Base64 Encoder/Decoder and the original comes straight back.

It is useful for exactly what it was designed for: putting an image in a data URL, attaching a file to an email, or sending binary data in JSON. A variant, Base64URL, swaps + and / for - and _ so the result is safe in web addresses.

Encoding, encryption and hashing

Encoding (Base64, hex, URL-encoding) Encryption (AES, ChaCha20) Hashing (SHA-256, bcrypt, Argon2)
Purpose Make data safe to transport Keep data secret Check data without storing it
Needs a key? No Yes No (passwords use a salt)
Reversible? Yes, by anyone Yes, only with the key No
Hides content? No Yes Yes, but guessable inputs can be found
Typical use Data URLs, email attachments, JSON Files, disks, connections Password storage, file integrity

The question to ask: who must not be able to read this? If the answer is "anyone", encoding does nothing for you.

Where does the confusion cause leaks?

HTTP Basic authentication

The header Authorization: Basic YWRtaW46aHVudGVyMg== is just admin:hunter2 in Base64. Basic auth is only acceptable over HTTPS, where the whole connection is encrypted. Over plain HTTP, or when the header ends up in a log or a shared screenshot, the password is in the clear.

JSON Web Tokens

A JWT looks like three blocks of random text separated by dots. The first two are just Base64URL-encoded JSON. Paste a token into JWT Decoder and you see everything in it: user ID, email, roles, expiry.

Two mistakes follow from thinking otherwise:

  • Putting secrets in the payload. Anything in a standard signed JWT is readable by whoever holds the token, including the user and anything that logs it. Keep payloads to identifiers and claims you would be happy for the user to see.
  • Trusting a token because it decodes. The signature proves the token was issued by someone holding the key and not altered since, but only when your server verifies it with that key. Decoding proves nothing. JWT Decoder deliberately shows a token as "Not expired · signature not checked", never as "valid", for this reason.

Configuration files and "obfuscated" keys

API keys and database passwords stored as Base64 in a config file, a mobile app or front-end JavaScript are as exposed as plain text. Anyone with the file can decode them. Kubernetes Secrets are a well-known example: by default their values are Base64-encoded, not encrypted, so anyone with read access to the Secret objects can read the values unless encryption at rest is configured.

URLs and logs

Developers sometimes Base64 personal data into a URL parameter to "hide" it: ?u=am9obkBleGFtcGxlLmNvbQ. URLs end up in browser history, server logs, analytics and the Referer header sent to other sites. Encoding does not change any of that.

What should I use instead?

You want to… Use
Keep a file or value secret Encryption with a proper key, e.g. AES-256-GCM
Store user passwords A slow password hash: Argon2, bcrypt or scrypt, never plain SHA-256 and never encryption
Keep API keys out of code Environment variables or a secrets manager, with encryption at rest
Prove data was not altered A signature or HMAC, verified on the receiving side
Send binary data through text Base64, which is exactly what it is for

For a single file you want to keep private, for example in cloud storage, Encrypt File seals it with AES-256-GCM, using a key derived from your password with PBKDF2 (SHA-256, 150,000 iterations). Without the password, the file is unreadable; with it, Decrypt File restores the original. Both run in the browser, so the file and password never leave your device. It writes its own .mgenc format, so use it for your own storage or for sending to someone who can use the same tool, not as a replacement for your application's encryption.

How do I spot Base64 in the wild?

Telltale signs: only letters, digits, + and / (or - and _), a length that is a multiple of 4, and often one or two = at the end. Common prefixes give the content away: eyJ is the start of encoded JSON ({"), so a string starting eyJ… with two dots is almost always a JWT. iVBORw0KGgo is the start of a PNG image, and JVBERi0 the start of a PDF.

When reviewing code or logs, decode suspicious strings with Base64 Encoder/Decoder. It detects the standard and URL-safe variants. If a decoded value is a password or a key, treat it as leaked: rotate it, then move it somewhere encrypted.

Quick answers

Is Base64 secure if I use a custom alphabet? No. A shuffled alphabet is a simple substitution that frequency analysis breaks quickly, and it gives a false sense of safety that is worse than none.

Is double Base64 encoding safer? No. Decoding twice takes a second step and no secret.

Should I hash or encrypt passwords? Hash them with a slow password hash. Encryption can be reversed by anyone who gets the key; a good password hash cannot be reversed at all.

Why do JWTs use Base64 if it isn't secure? Because they need to travel in headers and URLs as text. Their security comes from the signature (and, in encrypted JWTs, a separate encryption layer), not from the encoding.

What to do next

Decode the strings in your own config and logs with Base64 Encoder/Decoder, check what your tokens reveal with JWT Decoder, and keep sensitive files encrypted with Encrypt File.

Try the tool

Convert base64.

Open Base64 Encoder/Decoder →

More guides for Text Tools

Browse all Text Tools →