Skip to main content

How to Convert PFX to PEM Format in Batch Script

When moving security certificates from a Windows-native environment (which uses .pfx bundles) to a Linux-friendly or Open-Source environment (like Nginx, Apache, or HAProxy), you need to convert the format. These platforms typically require .pem files, which separate the public certificate from the private key into plain-text blocks. While Windows doesn't have a one-click "Export to PEM" button, a Batch script can automate this conversion using OpenSSL. This allows for a seamless, cross-platform pipeline where certificates can be managed in Windows and deployed anywhere.

This guide will explain how to translate PFX files into PEM format.

Prerequisite: OpenSSL for Windows

Standard Batch commands (certutil) are excellent for Windows-native tasks, but they do not cleanly handle the specific -----BEGIN PRIVATE KEY----- headers required by PEM-based systems. You should have OpenSSL installed (available via Git for Windows or stand-alone installers) to perform this conversion reliably.

Method 1: Exporting Both Key and Certificate (Standard)

This method creates a single .pem file containing the certificate, intermediate chain, and the private key.

@echo off
set "InFile=C:\Certs\mycert.pfx"
set "OutFile=C:\Certs\converted.pem"

:: Verify OpenSSL is available
where openssl >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] OpenSSL is not installed or not in PATH.
echo Install it via Git for Windows or a standalone package.
pause
exit /b 1
)

:: Verify the input file exists
if not exist "%InFile%" (
echo [ERROR] PFX file not found: %InFile%
pause
exit /b 1
)

echo [ACTION] Converting PFX to PEM...

:: Prompt for the PFX password rather than hardcoding it
set /p "Pass=Enter PFX password: "

:: -in = Input PFX
:: -out = Output PEM
:: -nodes = Don't encrypt the private key (Warning: Use with caution!)
openssl pkcs12 -in "%InFile%" -out "%OutFile%" -nodes -passin "pass:%Pass%"

if %errorlevel% equ 0 (
echo [SUCCESS] File saved to: %OutFile%
) else (
echo [ERROR] Conversion failed. Check your password and OpenSSL installation.
)

pause

Method 2: Separating the Private Key Only

Many Linux servers require the key to be in a separate file (e.g., server.key).

@echo off
set "InFile=C:\Certs\cert.pfx"
set "OutKey=C:\Certs\server.key"

:: Verify OpenSSL is available
where openssl >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] OpenSSL is not installed or not in PATH.
pause
exit /b 1
)

:: Verify the input file exists
if not exist "%InFile%" (
echo [ERROR] PFX file not found: %InFile%
pause
exit /b 1
)

echo [ACTION] Extracting Private Key...

set /p "Pass=Enter PFX password: "

:: -nocerts = Exclude the public certificate
openssl pkcs12 -in "%InFile%" -out "%OutKey%" -nocerts -nodes -passin "pass:%Pass%"

if %errorlevel% equ 0 (
echo [DONE] Key saved to: %OutKey%
) else (
echo [ERROR] Extraction failed. Check your password.
)

pause

Method 3: Extracting the Certificate Only

Common for sharing your public certificate with a load balancer.

@echo off
set "InFile=C:\Certs\cert.pfx"
set "OutCert=C:\Certs\server.crt"

:: Verify OpenSSL is available
where openssl >nul 2>&1
if %errorlevel% neq 0 (
echo [ERROR] OpenSSL is not installed or not in PATH.
pause
exit /b 1
)

:: Verify the input file exists
if not exist "%InFile%" (
echo [ERROR] PFX file not found: %InFile%
pause
exit /b 1
)

echo [ACTION] Extracting Public Certificate...

set /p "Pass=Enter PFX password: "

:: -nokeys = Exclude the private key
openssl pkcs12 -in "%InFile%" -out "%OutCert%" -nokeys -passin "pass:%Pass%"

if %errorlevel% equ 0 (
echo [DONE] Public cert saved to: %OutCert%
) else (
echo [ERROR] Extraction failed. Check your password.
)

pause

How to Avoid Common Errors

Wrong Way: Renaming the extension

Simply changing the filename from my.pfx to my.pem will not work. A PFX is a binary "Suitcase" containing encrypted data; a PEM is a plain-text document with specific headers.

Correct Way: Always use a cryptographic tool like OpenSSL to "Unpack" the binary PFX and "Re-encode" it as text-based PEM.

Problem: Password Prompts

If you don't use the -passin pass:xxxx flag in your script, OpenSSL will pause and wait for a human to type the password.

Solution: Use the -passin flag with a runtime-prompted password (Method 1) so your Batch script can run without interactive OpenSSL prompts. For fully unattended deployments, consider reading the password from a secured file using -passin file:password.txt.

Best Practices and Rules

1. Identify "Nodes" Security

The -nodes flag stands for "No DES" (meaning the private key in the PEM file is NOT password protected). This is required for most web servers (like Nginx) to start automatically without asking for a password, but it means anyone who gets the file can steal your key. Secure your PEM files with strict NTFS permissions.

2. Verify Output

Open the resulting .pem file in Notepad. It should start with -----BEGIN CERTIFICATE----- or -----BEGIN PRIVATE KEY-----. If it looks like gibberish, the conversion failed.

3. Cleanup Intermediate Files

When the conversion is complete, move the PFX and PEM files to a secure vault. Leaving them in a temp or downloads folder is a significant security risk.

Conclusions

Converting PFX to PEM via Batch script is a vital capability for any modern DevOps or system administration workflow. By moving beyond platform-locked formats and utilizing cross-platform tools like OpenSSL, you gain the flexibility to manage your certificates in Windows while deploying them to any infrastructure. This automated translation ensures your services remain secure and compatible, regardless of the operating system they run on.