Skip to main content
Security

Base64 is not encryption: matching the tool to the encoding job

Every developer has pasted a token into a "base64 decode" website at least once. It works, and it also quietly teaches a bad habit: your API keys, JWT payloads, and session tokens travel through somebody else's server to be decoded by a tool you know nothing about.

What each tool is actually for

Base64 is a transport format, nothing more. It converts binary data into printable characters so it can survive systems that mangle raw bytes, like email attachments or JSON payloads. It provides zero confidentiality. Anyone can decode it; the trailing = signs are not a lock, they are padding.

URL encoding solves a different problem: getting reserved characters through a query string. A space becomes %20, an ampersand becomes %26. If you build a query string by hand and skip this step, a & inside a parameter value silently splits into a second parameter. That bug has shipped to production a thousand times this year.

HTML entities exist for embedding text in markup. An unescaped < in user content is the textbook cross-site scripting vector, which is why the HTML entity converter exists as its own tool instead of people hand-rolling str_replace chains.

Hashing is the odd one out: it is one-way. You hash passwords so that a database leak does not hand over the originals. You never "decode" a hash, you compare hashes. Anyone advertising a "hash decoder" is selling rainbow tables.

Where these overlap in real work

Debugging a JWT means decoding the middle segment, which is base64url. The header and payload are not secret, only the signature protects them. That is worth internalizing: if your JWT contains data users should not read, decoding is trivial. The JWT decoder shows the payload side by side with the signature so you can see exactly what an attacker sees.

When something breaks in a pipeline, encoding confusion is a common culprit. The string aGVsbG8= in your logs might be double-encoded base64, or it might be a URL parameter that got base64'd on the way through. The base64 decoder and URL decoder both run entirely in your browser, which means the token you are debugging never leaves your machine.

A rule worth keeping

Before encoding anything, name the destination. Going into a URL? URL encoding. Going into HTML? Entities. Going through a binary-hostile transport? Base64. Getting stored for verification later? Hash it, with a real algorithm like bcrypt or argon2, never with the hash generator's MD5 (that tool is for checksums and fingerprinting, not passwords).

The mental model is simple: encoders change representation, hashes change representation irreversibly, and encryption (which none of these are) changes representation with a secret. Confusing the three is how "obfuscated" API keys end up in public repos and logs.