Convert PFX / PKCS#12 to PEM

To extract everything from a PFX into one PEM file, run `openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes`. Most of the time you want the pieces separately instead: `-nocerts -nodes` writes just the private key, `-clcerts -nokeys` writes just the server certificate, and `-cacerts -nokeys` writes just the CA chain. If OpenSSL 3 refuses the file with a "unsupported" or MAC error, add `-legacy`, because archives produced by older tools use RC2 or 3DES ciphers that OpenSSL 3 moved into its legacy provider.

Updated August 19, 2026 Verified against OpenSSL 3.5.7

Extract everything at once #

Certificate, chain and key into one PEM file
openssl pkcs12 -in certificate.pfx -out certificate.pem -nodes

OpenSSL asks for the archive’s import password. The result contains every object concatenated, which is fine for HAProxy but wrong for nginx and Apache, both of which want the key in a separate file.

Extract the pieces separately #

This is what you usually want. Three commands, one per output file:

Private key only
openssl pkcs12 -in certificate.pfx -nocerts -nodes -out private.key
Server certificate only
openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.crt
CA chain only
openssl pkcs12 -in certificate.pfx -cacerts -nokeys -out chain.crt

Replace these values

PlaceholderWhat to put there
-nocertsSuppress certificates, leaving only the private key.
-nokeysSuppress the private key, leaving only certificates.
-clcertsClient/end-entity certificate only — the one for your hostname.
-cacertsCA certificates only — the intermediate chain.
-nodesWrite the key unencrypted. Spelled -noenc in OpenSSL 3.

If OpenSSL 3 refuses the archive #

Archives written by older Windows tooling, older Java, or OpenSSL 1.x use RC2 or 3DES. OpenSSL 3 moved those algorithms into a legacy provider that is not loaded by default, and the resulting error usually looks like a MAC or password problem rather than an algorithm problem:

Load the legacy provider for this one command
openssl pkcs12 -legacy -in certificate.pfx -out certificate.pem -nodes

That specific failure is covered in full at unsupported MAC / PKCS#12 legacy errors.

Scripting it without a prompt #

Non-interactive extraction
openssl pkcs12 -in certificate.pfx -nocerts -nodes \
-passin pass:MyImportPassword -out private.key

Check what is in the archive before extracting #

Useful when you do not know whether the chain is even present:

openssl pkcs12 -in certificate.pfx -info -noout

One Certificate bag per certificate and one Shrouded Keybag for the key. If you see only a single certificate bag, there is no chain in the archive and -cacerts will produce an empty file.

Wiring the results into a web server #

nginx wants the leaf and chain concatenated into one file:

cat certificate.crt chain.crt > fullchain.crt
ssl_certificate     /etc/ssl/certs/fullchain.crt;
ssl_certificate_key /etc/ssl/private/private.key;

Apache 2.4.8 and later also read the chain from the certificate file:

SSLCertificateFile    /etc/ssl/certs/fullchain.crt
SSLCertificateKeyFile /etc/ssl/private/private.key

Before reloading, confirm the extracted key actually matches the extracted certificate — a mismatch here is the usual cause of a service that refuses to start:

openssl x509 -in certificate.crt -noout -pubkey | openssl sha256
openssl pkey -in private.key -pubout | openssl sha256

Frequently asked questions

What does -nodes do?
It writes the private key unencrypted. Without it, OpenSSL prompts for a new passphrase and encrypts the extracted key. Web servers that must start unattended need the unencrypted form. In OpenSSL 3 the flag is also spelled -noenc, which is clearer about what it does.
How do I split the output into separate files?
Use the selector flags rather than editing by hand. -nocerts gives you only the key, -clcerts only the end-entity certificate, and -cacerts only the chain. Running the command three times is cleaner and less error-prone than cutting one combined file apart.
Why is there a block of "Bag Attributes" text in my PEM file?
OpenSSL writes PKCS#12 bag metadata such as the friendly name and local key ID above each object. It is harmless and every implementation ignores it, but you can suppress it with -nomacver is not the answer — use openssl x509 or openssl pkey to re-emit just the object if you want a clean file.
Can I extract without knowing the password?
No. The private key inside a PKCS#12 archive is encrypted with a key derived from that password. Without it the archive is not recoverable by any tool, which is the entire point of the format.

References