How to turn a Base64 string into a PDF or image on Windows — nothing to install
An API response, an email source or a log hands you a long block of letters starting with something like JVBERi0 or iVBORw0KGgo, and what you actually need is the PDF or image it encodes. Most search results are upload-it-here decoder sites. Windows can do it locally with two built-in commands. Here is how, how to tell what kind of file the text holds, and the four things that make decoding fail — each one reproduced on this PC.

Paste the raw response and see its structure, so you copy exactly the field that holds the file. It runs in your browser; nothing is uploaded.
- ✓ Free
- ✓ No install, no sign-up
- ✓ Runs in your browser
- ✓ Files are never uploaded
🔒 Your file is never sent to a server or anywhere else — it is processed only in your own browser.
What a Base64 string is, and what is inside yours
Base64 writes binary data — a PDF, an image, any file — using only letters, digits, +, / and =. That lets a file travel inside JSON, an email or a web page. The cost is size: every 3 bytes become 4 characters.
You can usually tell what the text holds before decoding it, because every file type starts with the same few bytes, and those become the same few Base64 characters. Encoding the two test files here gave:
| Starts with | File type | Why |
|---|---|---|
| JVBERi0 | Every PDF begins with %PDF- | |
| iVBORw0KGgo | PNG | The fixed PNG signature |
So if a field begins JVBERi0, save the result as .pdf; if it begins iVBORw0KGgo, save it as .png. The extension you choose does not change the bytes, but it decides which program opens the file.
Method 1 — certutil, one line
certutil is a certificate tool that ships with Windows, and it happens to decode Base64. Save the Base64 text to a file first (Notepad is fine — just the characters, nothing else), then run this in Command Prompt or PowerShell:
certutil -decode C:\Users\you\Downloads\base64.txt C:\Users\you\Downloads\file.pdfHere it reported 'Input Length = 29100, Output Length = 21823' and a success line, and the PDF it wrote had exactly the same SHA-256 hash as the original — identical to the byte.
certutil will not overwrite. Run the same command again and it stops with ERROR_FILE_EXISTS (0x80070050). Add -f — certutil -f -decode ... — to replace the file.
Method 2 — PowerShell
PowerShell can do the same with .NET's Base64 converter. Paste this, changing the two paths:
$in = "C:\Users\you\Downloads\base64.txt" # the text file holding the Base64
$out = "C:\Users\you\Downloads\file.pdf" # the file to create (use a full path)
[IO.File]::WriteAllBytes($out, [Convert]::FromBase64String((Get-Content $in -Raw)))This also produced a byte-identical PDF. It copes with line breaks: the same Base64 wrapped every 76 characters decoded fine. That matters because email sources and many APIs break long Base64 into lines.
Use full paths. I set PowerShell's location to the test folder and wrote to a relative name — the file appeared in a different folder, the one .NET considered current (it does not follow cd). There was no error. Full paths avoid the hunt.
When it fails — the four causes
1. A data:...;base64, prefix
Base64 copied out of a web page or an HTML email often starts with data:application/pdf;base64,. Both tools reject it. PowerShell said: "The input is not a valid Base-64 string as it contains a non-base 64 character, more than two padding characters, or an illegal character among the padding characters." certutil failed with 0x8007000d (ERROR_INVALID_DATA). Delete everything up to and including the comma and both work.
2. URL-safe Base64 (- and _)
A variant of Base64 used in URLs and web tokens writes - instead of + and _ instead of /. The test PDF's Base64 contained 366 plus signs and 342 slashes; converted to the URL-safe form, PowerShell gave the same 'not a valid Base-64 string' error and certutil the same 0x8007000d. Swap the two characters back and it decodes.
3. The = at the end is missing
Base64 pads its length to a multiple of four with =. Some systems strip it. With the trailing == removed, PowerShell failed with "Invalid length for a Base-64 char array or string." — but certutil decoded it anyway and produced the correct file. So if PowerShell complains about length, try certutil before anything else.
4. certutil -encode output looks different
If you make Base64 with certutil -encode, the file starts with -----BEGIN CERTIFICATE-----, ends with -----END CERTIFICATE-----, and breaks lines every 64 characters — 457 lines for this PDF. certutil -decode reads that back happily, but PowerShell rejected the same file with the 'not a valid Base-64 string' error. Strip the two header lines before handing it to anything else.
The first three are fixed by one block. Run it in place of the last line of Method 2:
$s = (Get-Content $in -Raw).Trim()
if ($s -match '^data:[^,]*,') { $s = $s.Substring($s.IndexOf(',') + 1) } # remove data:...;base64,
$s = $s.Replace('-', '+').Replace('_', '/') # URL-safe -> standard
while ($s.Length % 4) { $s += '=' } # restore padding
[IO.File]::WriteAllBytes($out, [Convert]::FromBase64String($s))Run against all three broken versions of the test file — with the prefix, URL-safe, and without padding — each came out byte-identical to the original PDF.
A Python trap: garbage instead of an error
Python's base64.b64decode is lenient by default. Given the Base64 with the data: prefix still attached, it did not raise an error — it returned 21,842 bytes that began with u\xabZj instead of %PDF-. Saved as a PDF, that is a broken file you would only notice when it fails to open. With validate=True it stopped with 'Only base64 data is allowed', which is what you want.
import base64
text = open("base64.txt").read().strip()
data = base64.b64decode(text, validate=True) # validate=True: stop on anything that is not Base64
open("file.pdf", "wb").write(data)For URL-safe input use base64.urlsafe_b64decode — it decoded the URL-safe test file correctly. Missing padding still fails in Python ('Incorrect padding'), just as it does in PowerShell. Tested with Python 3.11.9.
The options side by side
| certutil | PowerShell | Python b64decode | |
|---|---|---|---|
| Install needed | No (built in) | No (built in) | Python |
| Plain Base64 | Identical file | Identical file | Identical file |
| Line breaks every 76 | Not tested | Works | Not tested |
| data:...;base64, prefix | Fails (0x8007000d) | Fails (error) | Silent garbage — use validate=True |
| URL-safe - and _ | Fails (0x8007000d) | Fails (error) | Use urlsafe_b64decode |
| Missing = padding | Works | Fails (length error) | Fails (Incorrect padding) |
Online decoders work too, but they mean pasting the content somewhere else. A Base64 PDF from an API is often an invoice, a contract or an ID document — exactly what you would not want to upload. Both Windows methods keep it on your PC.
FAQ
Q. How do I know whether the Base64 is a PDF or an image?
Look at the first characters. JVBERi0 decodes to %PDF-, so it is a PDF; iVBORw0KGgo is the PNG signature. Save with the matching extension.
Q. certutil says the data is invalid (0x8007000d).
Usually a data:...;base64, prefix or URL-safe characters (- and _). Delete everything up to the comma, swap - for + and _ for /, and run it again.
Q. PowerShell says 'Invalid length for a Base-64 char array or string'.
The = padding at the end was stripped. Add = until the length is a multiple of four, or decode with certutil, which accepted the unpadded text here.
Q. PowerShell worked but I can't find the file.
A relative output path is resolved against .NET's current folder, which does not follow cd. Use a full path such as C:\Users\you\Downloads\file.pdf.
Q. Is anything uploaded?
No. certutil and PowerShell both run on your PC with nothing installed.
Paste the raw response and see its structure, so you copy exactly the field that holds the file. It runs in your browser; nothing is uploaded.
- ✓ Free
- ✓ No install, no sign-up
- ✓ Runs in your browser
- ✓ Files are never uploaded
🔒 Your file is never sent to a server or anywhere else — it is processed only in your own browser.
Comments 0
No comments yet. Be the first.
Only members can comment.
Comments with ads, abuse, personal information or illegal content are hidden or removed. Comments are shown with your nickname. Privacy Policy