Encoding vs Encryption vs Hashing
Three commonly confused transformations compared: what's reversible, what needs a key, and why Base64 is not encryption.
Encoding, encryption, and hashing all transform data into a different shape, which is exactly why they get mixed up. They exist for three unrelated purposes: encoding is about compatibility, encryption is about confidentiality, and hashing is about integrity and verification. Using one where another is needed is a real, common security mistake — most often, treating Base64 as if it were encryption.
Side by side
| Encoding | Encryption | Hashing | |
|---|---|---|---|
| Purpose | Safe transport / storage in a system with format restrictions | Keep data secret from anyone without the key | Verify integrity or store a value without keeping the original |
| Reversible? | Yes, always, no key needed | Yes, but only with the correct key | No — one-way by design |
| Needs a secret? | No | Yes (a key) | No (though a salt is added for password storage) |
| Example | Base64, URL encoding | AES, RSA | SHA-256, bcrypt |
Encoding: making data fit, not hiding it
Encoding schemes like Base64 or percent-encoding exist because some systems only accept a limited character set — an email body, a URL, a JSON string — and the data to embed (binary content, or characters the format reserves for its own syntax) does not fit as-is. Encoding re-represents the same data using an allowed character set. Anyone can reverse it instantly with no secret required: it is a public, standardized, two-way transformation, not a security measure of any kind.
Encryption: reversible, but only with the key
Encryption scrambles data using an algorithm and a secret key, producing ciphertext that is computationally infeasible to reverse without that key. Symmetric encryption (AES) uses the same key to encrypt and decrypt — fast, used for encrypting data at rest or in transit once a shared key is established. Asymmetric encryption (RSA) uses a public key to encrypt and a separate private key to decrypt — slower, but solves the problem of exchanging a secret over an insecure channel in the first place.
A standard JWT is signed, not encrypted: its payload is Base64url-encoded (reversible by anyone) and a signature proves it was not tampered with, but the claims inside remain fully readable without any key. Actual JWT encryption (JWE) is a distinct, less common variant.
Hashing: one-way, for verification
A hash function maps input of any size to a fixed-size digest, and — deliberately — there is no inverse operation to recover the input from the digest. This is exactly the property needed for storing passwords: the server never needs to store or read back the original password, only compare a freshly computed hash against the stored one. It is also used to verify a downloaded file was not corrupted or tampered with, by comparing its hash against a published value.
For password storage specifically, a fast general-purpose hash (SHA-256) is the wrong tool — see What is a Hash Function? for why bcrypt/Argon2/scrypt exist, and Password Strength and Entropy for what actually makes a password resistant to guessing in the first place.
The most common mistake: Base64 is not encryption
Base64-encoding a password or API key and calling it "encrypted" is a frequent, genuine security bug. Base64 has no key and no secret — decoding it back to plaintext takes one line of code in any language, or a five-second paste into an online decoder. If a value needs to stay secret, it needs encryption (or, if it is a credential being verified rather than retrieved, hashing) — encoding alone provides exactly zero confidentiality.
Try it now
Frequently asked questions
No. Base64 has no key and no secret of any kind — decoding it back to the original data takes one line of code in any language. It exists purely so binary or special-character data can safely pass through systems that only accept a limited character set.
If a value needs to stay confidential, it needs encryption. Base64-encoding a password or API key and treating it as protected is a genuine, common security bug.