A common misconception
"Let me Base64 the password so it is safe" — a frequent beginner mistake. Base64 looks like gibberish, but it has nothing to do with encryption: Base64 is encoding, not encryption.
The fundamental difference
- Encoding exists so data can travel or be stored safely. It is fully reversible and needs no key — anyone can decode it instantly.
- Encryption exists so people without the key cannot read the data. It depends on a key.
- Hashing is one-way, used to verify integrity or store password digests.
Base64 maps binary data onto 64 printable characters (A-Z, a-z, 0-9, +, /) so it can travel through text-only channels such as email, URLs and JSON.
Recognize it at a glance
- Characters are limited to A-Z, a-z, 0-9, + and /;
- Length is a multiple of 4: 3 bytes become 4 characters, roughly +33% in size;
- It often ends with
=or==padding.
Which one to use
Carrying binary data inside a text protocol (inline images, JWT, attachments)? Use Base64. Need secrecy? Use symmetric encryption such as AES with a random key. Need to verify nothing changed? Use a hash like SHA-256. They are often combined, but never interchangeable.
A practical decision table
| Goal | Use | Why |
|---|---|---|
| Carry binary inside JSON / URL / email | Base64 | Reversible, keyless — solves transport only |
| Keep data unreadable to others | Symmetric encryption (AES-GCM) | Undecryptable without the key, and tamper-evident |
| Check whether a file changed | Hashing (SHA-256) | One-way; a single changed bit yields a totally different digest |
| Store user passwords | bcrypt / Argon2 | Built-in salt and slow hashing raise brute-force cost |
Code examples
// Browser: convert to UTF-8 bytes first, or btoa throws on non-Latin-1
const encoded = btoa(String.fromCharCode(...new TextEncoder().encode('hello')));
const decoded = new TextDecoder().decode(
Uint8Array.from(atob(encoded), c => c.charCodeAt(0))
);
// Node.js: UTF-8 is native — easiest option
const b64 = Buffer.from('hello', 'utf8').toString('base64');
const back = Buffer.from(b64, 'base64').toString('utf8');
Three common mistakes
- Treating Base64 as encryption: hiding a password this way is undone by one line of decoding;
- Calling btoa on non-ASCII text: it only accepts Latin-1 and throws otherwise — encode to bytes first;
- Inlining large files as Base64: about 33% bigger and it delays first paint — skip it beyond a few KB.
Follow-up questions
Why does JWT use Base64Url? Because + and / get escaped or truncated inside URLs, so JWT swaps them for - and _ and drops the = padding. Does Base64 compress data? No — it grows the payload; it only makes it printable.
Try them: Base64 encoder/decoder, symmetric encryption, hashing
Explaining the distinction to others
The confusion is usually about wording, not understanding. These analogies work well.
- Envelope versus safe: Base64 puts a document in a standard envelope anyone can open; encryption locks it in a safe. They solve entirely different problems.
- Interchange versus access control: encoding exists so different systems can read the data; encryption exists so the wrong people cannot. Mistaking format conversion for access control is using the tool backwards.
- How you verify: to test whether data is merely encoded, try decoding it; to test encryption, check whether you hold a key. This is the most overlooked and most clarifying point.
- They combine in practice: real systems encrypt for confidentiality, encode for transport and hash or sign for integrity, each layer doing its own job.
Making it stick in a team
Write "never substitute encoding for encryption" into your conventions, and treat "it looks like gibberish" as a red flag in review rather than proof of safety. Provide a shared encryption utility and key-management process so the right path is the easier path — only then does the rule get followed.
How to document it
Put a comparison table in your docs: purpose, reversibility, key requirement and integrity verification. Keeping those four columns visible catches most misuse during design rather than in a security review, and onboarding should cover it — it is a baseline concept.