The distinction people get wrong
Base64 is not encryption — it's a reversible encoding with a public, documented algorithm and no key. Anyone can decode Base64 instantly; its only purpose is representing arbitrary bytes with printable characters (email attachments, data URLs, JSON-embedded binaries). Encryption, by contrast, is reversible only with a key, and its security rests entirely on that key's secrecy.
The test that settles it
Ask: "Can a stranger who intercepts this recover the content?" If yes — it's encoding. Base64 "protecting" an API credential is obfuscation at best; scrapers and scanners decode it on sight. Credentials in transit need TLS; credentials at rest need AES or age; user passwords need a slow hash (bcrypt/Argon2), which isn't reversible at all.
Where each belongs
| You need… | Use |
|---|---|
| Binary in text (email, JSON, URLs) | Base64 / Base64URL |
| Only the right party can read it | AES-GCM (symmetric) or RSA/ECIES (asymmetric) |
| Nobody can read it, ever — even you | bcrypt / Argon2id hash (passwords) |
| Proof a message is unmodified | HMAC (keyed) or SHA-256 (unkeyed integrity) |
Encoding facts worth knowing
- Base64 inflates size by ~33% (3 bytes → 4 chars). Base64URL (
-_instead of+/, no padding) exists for URL-safe contexts — JWTs use it. - Hex doubles size but survives case-insensitive contexts and eyeball comparison; hashes are conventionally hex.
- Encoding isn't compression either — it makes data bigger. Pair with gzip before Base64 if size matters.
A real-world checklist
Before shipping: secrets in git are not "hidden" by Base64 (scanners decode them); "encrypted" client-side with a key shipped in the same JavaScript is encoding with extra steps; JWT payloads are Base64URL — signed, not encrypted — so never put secrets in one. Verify all of this hands-on in the Base64 and Encrypt/Decrypt tools — both fully client-side.