Base64 shows up everywhere. JWTs use it for their header and payload sections. CSS data URIs embed images with it. HTTP Basic Auth encodes credentials in it. Email attachments use it. Yet despite being this ubiquitous, it's frequently misunderstood — people assume it provides some form of security, or they're fuzzy on why it exists at all.
Here's the full picture.
Why Base64 Exists
Binary data — images, audio files, compiled code — can contain any byte value from 0 to 255. Many text-based protocols and systems are designed to handle a much narrower range of safe characters. Email systems historically corrupted binary data that contained certain control bytes. URLs have characters with special meaning that can't appear unescaped. JSON strings can't contain raw binary.
Base64 solves this by converting arbitrary binary data into a string using only 64 printable ASCII characters: A-Z, a-z, 0-9, +, and /. The = character is used for padding. That "alphabet" of 64 safe characters is what gives the encoding its name.
The result can travel safely through any system that handles ASCII text, regardless of what the original binary contained.
How the Algorithm Works
The encoding process takes 3 bytes of input at a time and converts them into 4 output characters.
3 bytes = 24 bits. Split those 24 bits into four groups of 6 bits each. Each 6-bit group can represent a value from 0 to 63 — which maps to one of the 64 characters in the Base64 alphabet.
Let's trace "Man" as an example:
M a n
01001101 01100001 01101110 (binary)
010011 010110 000101 101110 (split into 6-bit groups)
19 22 5 46 (decimal values)
T W F u (Base64 alphabet lookup)
So "Man" encodes to "TWFu". You can verify this yourself with the Base64 Encoder.
Padding
If the input isn't a multiple of 3 bytes, padding characters (=) are added:
- 1 leftover byte → 2 Base64 characters +
== - 2 leftover bytes → 3 Base64 characters +
=
"Ma" (2 bytes) encodes to "TWE=". "M" (1 byte) encodes to "TQ==".
The Size Cost
Converting 3 bytes to 4 characters means Base64 always increases size by approximately 33%. A 100KB image becomes ~133KB when Base64-encoded. For a 1MB PDF, that's an extra ~333KB.
This matters when you're deciding whether to inline images as data URIs or serve them as separate requests. For small icons (under a few hundred bytes), inlining wins — you save an HTTP round-trip. For anything larger, the size penalty usually outweighs the savings.
Base64 vs Base64url
Standard Base64 uses + and / as characters 62 and 63, and = for padding. These characters have special meanings in URLs and HTTP headers — + means a space in form encoding, / is a path separator.
Base64url is a URL-safe variant that replaces:
+with-/with_- Strips the
=padding
This is what JWTs use. The three sections of a JWT — header, payload, and signature — are all Base64url-encoded, not standard Base64. If you try to decode a JWT section with a standard Base64 decoder and it fails, that's why. The Base64 Encoder tool handles both variants.
Standard Base64 and Base64url encode to different strings but decode to the same bytes. They're not different encoding schemes — just different alphabets for the same algorithm.
Common Use Cases
JWTs
As covered in JWT Tokens Explained, the header and payload of a JWT are Base64url-encoded JSON objects. They're not encrypted — anyone can decode them. The signature is what prevents tampering.
HTTP Basic Authentication
The Authorization: Basic <credentials> header contains username:password encoded in Base64:
username:password → dXNlcm5hbWU6cGFzc3dvcmQ=
This is encoding, not encryption. Anyone who intercepts the header can trivially decode it. Basic Auth should only ever be used over HTTPS.
CSS Data URIs
You can embed an image directly in a stylesheet without a separate HTTP request:
background-image: url("data:image/png;base64,iVBORw0KGgo...");
The browser decodes the Base64 string to get the raw image bytes. Useful for small icons and background images to eliminate extra HTTP requests, though the 33% size overhead means it's only worth it for small assets.
Email Attachments (MIME)
The MIME standard uses Base64 to encode binary attachments in email messages. When you open an email attachment, your client is decoding a Base64 string to reconstruct the original file. This is why email has been transporting files safely since long before HTTP file uploads were reliable.
Storing Binary Data in JSON or Text Formats
JSON has no binary type. If you need to include binary data in a JSON payload — an image thumbnail, a cryptographic key, a certificate — Base64 encoding is the standard approach.
What Base64 Is Not
Base64 is not encryption. It provides no security whatsoever.
Anyone can reverse it without a key. It obscures content from a casual glance, but any developer can decode it in seconds. Don't use it to hide passwords, API keys, or sensitive data — you're not protecting anything, you're just making it slightly less readable.
For actual security, you need:
- Encryption — transforms data with a key so only key holders can reverse it
- Hashing — one-way transformation for integrity checking and password storage
The Hash Generator handles cryptographic hashing. For actual encryption needs, look to established libraries (libsodium, OpenSSL, Web Crypto API) with properly chosen algorithms.
Encoding URLs and Query Parameters
Base64 is sometimes confused with URL encoding, which is a different thing entirely. URL encoding (percent-encoding) escapes characters that have special meaning in URLs using %XX hex codes. The URL Encoder handles this case.
The distinction matters when you're passing Base64-encoded data as a URL parameter. Standard Base64 output contains +, /, and = — all of which need to be URL-encoded if they appear in a query string. Base64url output avoids this problem entirely, which is another reason it's preferred for anything HTTP-related.
Decoding in Practice
Most languages have Base64 support built in or in a standard library:
// Browser / Node.js
btoa("hello") // encode → "aGVsbG8="
atob("aGVsbG8=") // decode → "hello"
// For binary data in Node.js
Buffer.from(data).toString("base64")
Buffer.from(encoded, "base64")
import base64
base64.b64encode(b"hello") # b'aGVsbG8='
base64.b64decode(b"aGVsbG8=") # b'hello'
# URL-safe variant
base64.urlsafe_b64encode(b"hello")
The base64.guru reference covers encoding details and edge cases for various implementations.
For more on encoding schemes that come up alongside Base64, read Encoding vs Encryption vs Hashing — the distinctions between these three concepts are worth knowing clearly.
Wrapping Up
Base64 is an encoding scheme for making binary data text-safe — nothing more. It's everywhere because text-based protocols are everywhere. The 33% size overhead is the cost of portability. The security situation is simple: it provides none. When you need to encode and decode Base64 quickly without writing code, the Base64 Encoder handles both standard and URL-safe variants.