How to Decode Base64: Text, Images and JWT Tokens Explained

You open an API response, a config file or the source of an email, and somewhere in the middle sits a line like this:

SGVsbG8sIFdvcmxkIQ==

It looks like a cat walked across the keyboard. It isn’t random, though. Run it through a Base64 decoder and it reads “Hello, World!”

Base64 shows up in login tokens, email attachments, embedded images and API payloads. Most people only think about it when something breaks. This guide shows you how to decode Base64 step by step, whether you are working with text, images or JWT tokens, and how to fix the errors that eat up an afternoon.

Quick answer: how to decode Base64

A Base64 decoder turns Base64-encoded text back into its original data. That data might be plain text, an image, a PDF or the JSON inside a login token. Base64 is an encoding, not encryption, so decoding needs no password or key. Anyone can reverse it.

That last point has real privacy consequences, and we’ll get to them below.

What is Base64, and why does it exist?

Computers store everything as bytes. Many older systems, email being the classic example, were designed to carry plain text only. Push raw binary data such as an image or a ZIP file through them and it can get corrupted or rejected.

Base64 gets around this by rewriting any data using a safe alphabet of 64 characters:

  • Uppercase letters A to Z
  • Lowercase letters a to z
  • Digits 0 to 9
  • Two symbols: + and /
  • The = sign, used as padding at the end

The format is defined in RFC 4648. The price you pay is size. Every 3 bytes of input become 4 characters of output, so Base64 data is about one third larger than the original. A 1,024-byte file turns into 1,368 characters.

How Base64 decoding works (a small worked example)

You will almost never decode by hand. Still, seeing it once makes the errors later much easier to understand.

Take the string TWE=. Decoding goes like this:

  1. Each character maps to a number from 0 to 63. T is 19, W is 22 and E is 4.
  2. Each number becomes 6 bits: 010011, 010110, 000100.
  3. Join them into one stream: 010011010110000100.
  4. Regroup into 8-bit bytes and discard the leftover bits: 01001101 is “M” and 01100001 is “a”.

The result is “Ma”. The = told the decoder that the last group was short, so it knew to throw away the extra bits.

That is the whole reason padding exists, and it explains why a missing = is one of the most common decode failures:

Original lengthExampleBase64 outputPadding
Multiple of 3 bytesManTWFuNone
Leaves 2 bytes overMaTWE=One =
Leaves 1 byte overMTQ==Two ==

Where you’ll run into Base64

Where it appearsWhat’s insideWhy Base64 is used
Email attachments (MIME)Documents, imagesEmail was built to carry text
Data URIs in HTML and CSSSmall images, fontsAvoids a separate file request
JWT tokensJSON header and payloadCompact and URL-friendly
API requests and responsesFiles, binary dataJSON strings cannot carry raw binary
PEM filesCertificates, keysBinary data stored as plain text
HTTP Basic Auth headersusername:passwordHeader formatting, not security

If you work with web apps or APIs, you will run into several of these sooner or later.

How to decode Base64 to text

For plain text, the job is simple: paste the string into a decoder and read the output. Two things trip people up.

Character encoding. Base64 decodes to bytes, and bytes only turn into readable text when they are interpreted with the right character set. UTF-8 is the most widely used one. If you see é where you expected é, the text was read with the wrong encoding.

The atob() trap in JavaScript. The browser’s built-in atob() returns a “binary string” with one character per byte. That is fine for plain ASCII, but emoji and non-English characters come out garbled. For UTF-8 text, convert the bytes with TextDecoder instead.

If you would rather decode in code, these are the usual one-liners:

EnvironmentHow to decode
Node.jsBuffer.from(str, 'base64').toString('utf8')
Browser JavaScriptatob(str) (ASCII only; use TextDecoder for UTF-8)
Pythonbase64.b64decode(str)
Linux (GNU coreutils)echo 'str' | base64 --decode
PowerShell[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("str"))

One note for Python users: base64.urlsafe_b64decode() expects correct padding, and JWT segments have their padding stripped. If you get an “Incorrect padding” error, add = characters until the length is a multiple of 4.

How to convert Base64 to an image or file

Decoding to a file works the same way, except you save the bytes instead of reading them as text. Two details make it easier.

Data URIs label themselves. If your string starts with data:image/png;base64,, the part before the comma tells you the file type and the part after is the actual data. Remove the prefix before decoding.

Raw Base64 still hints at the file type. Most file formats begin with a recognizable signature, and that signature stays recognizable after encoding:

Starts withUsually means
iVBORw0KGgoPNG image
/9j/JPEG image
R0lGODGIF image
JVBERi0PDF document

If you have an unlabelled string and no idea what it is, check the first few characters. It is a quick way to pick the right file extension before you save anything.

A quick performance note: embedding Base64 images directly in HTML or CSS saves a network request, but it makes the data about a third bigger and stops the browser from caching the image on its own. It suits tiny icons. It is a poor fit for photos.

How to decode a JWT token

A JSON Web Token (JWT), specified in RFC 7519, looks like three Base64URL chunks separated by dots:

header.payload.signature

PartWhat it containsReadable by decoding?
HeaderToken type and signing algorithm (such as HS256 or RS256)Yes
PayloadClaims: who the user is, when the token expiresYes
SignatureProof the token wasn’t alteredIt decodes, but only means something when checked with the key

The payload usually carries a few standard claims:

ClaimMeaning
issIssuer: who created the token
subSubject: usually the user ID
audAudience: who the token is meant for
iatTime the token was issued
nbfToken is not valid before this time
expTime the token expires

Time claims are Unix timestamps in seconds, not milliseconds. This causes a classic bug. JavaScript’s Date.now() returns milliseconds, so comparing it directly with exp gives wrong results. Going the other way, new Date(exp) without multiplying by 1,000 gives you a date in January 1970. Convert the units first and the confusion disappears.

Decoding is not verifying

Decoding a JWT shows you what the token claims. It does not prove those claims are true. Only someone holding the secret or public key can verify the signature. For debugging, decoding is exactly what you need. For deciding who gets access to what, verification on the server is the only thing that counts.

Also remember that a standard signed JWT is encoded, not encrypted. Anyone who holds it can read the payload, so never put passwords, card numbers or sensitive personal data inside. Encrypted tokens (JWE) do exist, but they have five parts and cannot be read by simple Base64 decoding.

Standard Base64 vs URL-safe Base64

The + and / characters cause trouble inside URLs, where they carry special meanings. So a variant called Base64URL swaps them out:

Standard Base64URL-safe Base64
Character 62+-
Character 63/_
Padding =UsedOptional; left out in JWTs
Commonly found inEmail, files, general dataJWTs, URL parameters

If a decoder rejects your string with an “invalid character” message and you can see - or _ in it, you almost certainly have the URL-safe version.

Common Base64 decode errors and how to fix them

What you seeLikely causeFix
“Invalid character”URL-safe string fed to a standard decoderReplace - with + and _ with /, or use a decoder with a URL-safe option
“Incorrect padding”Trailing = was lost while copyingCopy the full string again, or add = until the length is a multiple of 4
Garbled textWrong character encoding, or the data isn’t textTry UTF-8; if it’s a file, decode it as a file
Output still looks like Base64The data was encoded twiceDecode the result once more
Unreadable symbolsThe data was compressed or encrypted before encodingThe decode worked; the next step is decompression or decryption
Works on one line, fails on severalLine breaks inside the stringRemove whitespace, or decode line by line

Go through that list from top to bottom and you will find the cause most of the time.

Is Base64 encryption? (No, and it matters)

This is the biggest misunderstanding around Base64. Encoding changes the format of data so systems can handle it. Encryption hides data from anyone without a key. Base64 only does the first job.

Treat anything in Base64 as plain text wearing a thin disguise. A few practical rules follow from that:

  • Don’t store secrets in Base64 and call them protected. A Basic Auth header is just username:password in Base64, readable by anyone who sees it.
  • Think about where you paste real tokens. Before using any online tool with sensitive data, read how it handles your input.
  • Never run decoded content you didn’t write. Base64 is sometimes used to obfuscate malicious scripts. Decode to read, not to execute.

How to choose an online Base64 decoder

Almost any tool can turn SGVsbG8= into “Hello”. The differences show up when your input isn’t tidy. Here is a simple checklist:

What to checkWhy it matters
Text, file and JWT supportReal work involves more than plain text
URL-safe inputJWTs and URL parameters use this variant
Image previewConfirms you decoded the right thing
Clear error messages“Invalid input” tells you nothing; a specific hint saves time
Batch decodingUseful when you have a list of values
Privacy statementTells you what happens to what you paste

Features differ from tool to tool, so make sure the ones you need are actually there.

Need to decode something right now?

If you have a string in front of you and just want to see what’s inside, you can paste it into the Base64 decoder on BytePriva. And when you need to go the other way, there is a Base64 encoder too.

Frequently asked questions

What is a Base64 decoder?

A Base64 decoder converts a Base64-encoded string back into its original form, whether that is text, an image, a file or structured data such as a JWT payload.

Is Base64 encryption?

No. Base64 is a reversible encoding with no key or password. Anyone can decode it, so it provides no security on its own.

Why does Base64 end with == or =?

The equals signs are padding. Base64 works in groups of 3 bytes. When the input doesn’t divide evenly, one or two = characters complete the last group.

How do I decode Base64 to an image?

Remove the data:image/...;base64, prefix if there is one, decode the rest into bytes, and save the bytes with the matching extension such as .png or .jpg. A decoder that supports files will do this and show a preview.

Can I decode a JWT without the secret key?

Yes. The header and payload are only Base64URL-encoded, so you can read them without any key. You cannot verify the signature without the secret or public key.

What is the difference between Base64 and Base64URL?

Base64URL replaces + with - and / with _, and often omits the padding, so the result is safe to use inside URLs. JWTs use this variant.

Why is my decoded text full of strange characters?

Usually one of two things: the text was read with the wrong character encoding (try UTF-8), or the original data wasn’t text at all, for example an image, a compressed file or encrypted data.

Does Base64 make files bigger?

Yes, by roughly 33 percent, because every 3 bytes of data become 4 characters.

Is it safe to decode Base64 online?

It depends on the tool. Decoding is harmless in itself, but the concern is where your input goes. For tokens, keys or private files, use a decoder that processes data locally in your browser and states so clearly, and avoid pasting live production secrets anywhere you don’t trust.

Can Base64 hide malware?

It can. Base64 is often used to obfuscate scripts, which is why security teams decode suspicious strings during analysis. If you decode something you don’t recognise, read it and don’t execute it.

Key takeaways

  • Base64 carries binary data through text-only channels. It does not protect that data.
  • Most decode errors come from padding, URL-safe characters, character encoding or stray whitespace.
  • Anyone holding a JWT can read its payload, and decoding says nothing about whether it is authentic.
  • JWT time claims are in seconds, which catches out many developers.
  • For sensitive data, check how a tool handles your input before pasting it.

Disclaimer

This article is for general educational purposes only. Decoding Base64 only reveals data; it does not confirm that the data is authentic or safe, so never run or trust decoded content from an unknown source. Test any code examples in a safe environment before using them in production, and avoid pasting real passwords, private keys or live secrets into online tools.

Related Guides

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top