Encoding vs. Hashing vs. Encryption — and Why Base64 Isn't a Security Feature
The three most confused words in developer tooling, untangled: what each one actually does, when to use which, and the mistakes that keep happening because they get mixed up.
"Is Base64 encryption?" is one of the most common questions we see about our own tools, and the honest answer is: no, not even close. Encoding, hashing and encryption get lumped together constantly because they all turn readable data into something that doesn't look readable — but they solve three completely different problems, and mixing them up has caused real security bugs.
The one-line version
- Encoding — reversible, no key required, exists for compatibility. Base64 is encoding.
- Encryption — reversible only with the right key, exists for confidentiality. AES, RSA are encryption.
- Hashing — irreversible, no key, exists for integrity/verification. SHA-256, MD5 are hashing.
If you remember nothing else from this post, remember that only one of these three — encryption — is designed to keep data secret. The other two were never trying to.
Encoding: making data safe to transport, not safe to read
Encoding schemes like Base64 exist because some systems can only reliably carry certain characters. Email was built for 7-bit ASCII text; a lot of infrastructure was built assuming "text" means printable characters, not arbitrary binary. Base64 solves that by representing any data — including binary — as a string built from just 64 printable characters (A–Z, a–z, 0–9, + and /).
Critically, decoding Base64 requires no secret. Anyone, with no key and no special tool beyond a text editor and five minutes, can turn a Base64 string back into its original form. That's not a flaw — it's the whole point. Encoding was never trying to hide anything.
This is exactly why a JWT's payload — which is Base64url-encoded, not encrypted — can be read by anyone who has the token, even though it's not signed by them. If you've ever seen someone say "I encoded the API key so it's not stored in plain text," that's the mistake this post is about: encoding a secret doesn't protect it. It just makes it look protected.
Encryption: reversible, but only with the key
Encryption is the one of these three actually designed for confidentiality. You encrypt data with a key, and only someone holding the correct key (the same key, for symmetric algorithms like AES; the matching private key, for asymmetric algorithms like RSA) can decrypt it back to the original.
The security here lives entirely in the key, not in the algorithm being secret — well-designed encryption assumes an attacker knows exactly which algorithm you used and still can't read your data without the key. That's a deliberate design principle (Kerckhoffs's principle, if you want the name for it), and it's why "we invented our own secret encoding scheme" is almost always a worse idea than using a standard, publicly-scrutinized encryption algorithm.
Hashing: proving data wasn't changed, not hiding it
Hashing takes an input of any size and produces a fixed-size fingerprint — a digest. The same input always produces the same digest, but there's no key involved and, crucially, no way back: you cannot take a hash and recover the original input. That one-way property is the entire point of a hash function, which is why "reversing a hash" isn't a thing you do — at best, an attacker can guess likely inputs and check if they hash to the same value (which is exactly why hashing a password with no salt, using a fast algorithm, is dangerous — see below).
Hashing answers a different question than encryption or encoding: not "what does this say" or "can this travel safely as text," but "does this match what I expect?" That's why every git commit is identified by a hash of its contents, why package managers publish checksums so you can verify a download wasn't corrupted, and why file-integrity tools flag a file the moment its hash changes.
Where the mistakes actually happen
A few real, recurring mix-ups:
- Treating Base64 as if it hides data. It doesn't. If something needs to stay secret, it needs encryption, not encoding.
- Using a fast, general-purpose hash (MD5, SHA-256) for passwords. Hashing is correct for password storage in principle — you never want to store a reversible password — but MD5 and plain SHA-256 are fast, which means an attacker with a list of common passwords can hash millions of guesses per second and check for a match. Password hashing needs an algorithm deliberately made slow and salted (bcrypt, scrypt, Argon2), which is a different tool for a related-but-distinct job.
- Assuming "hashed" means "safe to log/share." A hash of a value is not the value, but for low-entropy inputs (a 4-digit PIN, a common password) it can still be reversed by brute force. Don't treat a hash as automatically safe to expose just because it's not the plaintext.
In practice
Reach for encoding when you need to move data through a system that can't handle raw bytes or the character you're using (Base64, URL-encoding). Reach for encryption when the data must stay confidential from anyone without the key. Reach for hashing when you need to verify integrity or store something you'll only ever need to check against, never retrieve, like a properly-salted password hash.
Try it yourself: Base64 Encode / Decode and Hash Generator both run entirely in your browser — nothing you type is uploaded, which incidentally is also true of every other tool on this site.