Convert PEM to PFX / PKCS#12

To convert PEM to PFX, run `openssl pkcs12 -export -out certificate.pfx -inkey private.key -in certificate.crt -certfile chain.crt`. This bundles the certificate, its private key and any intermediate CA certificates into one password-protected PKCS#12 file. If the resulting file is rejected by Windows, IIS or a Java keystore, re-export it with the `-legacy` flag, because OpenSSL 3.x encrypts PKCS#12 files with AES-256-CBC by default and older implementations only understand the RC2 and 3DES ciphers.

Updated August 19, 2026 Verified against OpenSSL 3.5.7

The command #

Bundle certificate, key and chain into one PFX
openssl pkcs12 -export \
-out certificate.pfx \
-inkey private.key \
-in certificate.crt \
-certfile chain.crt

OpenSSL prompts twice for an export password. That password protects the private key inside the archive, and whoever imports the file will need it.

Replace these values

PlaceholderWhat to put there
certificate.pfxThe PKCS#12 file to create. .p12 is the same format.
private.keyPEM private key that matches the certificate.
certificate.crtThe end-entity (server) certificate, PEM-encoded.
chain.crtIntermediate CA certificates, concatenated. Omit -certfile if you have none.

Doing it non-interactively #

In a script or CI job you cannot answer a password prompt. Pass the password on the command line instead:

Scripted export with an explicit password
openssl pkcs12 -export \
-out certificate.pfx \
-inkey private.key \
-in certificate.crt \
-certfile chain.crt \
-passout pass:MyExportPassword

If the PFX is rejected by Windows, IIS or Java #

OpenSSL 3.0 changed the default PKCS#12 encryption to AES-256-CBC with PBKDF2 and the MAC to SHA-256. That is the correct modern choice, but implementations written against the original PKCS#12 spec cannot read it, and they usually report the failure as a wrong password rather than an unsupported cipher.

Export using the legacy algorithms older importers understand
openssl pkcs12 -export -legacy \
-out certificate.pfx \
-inkey private.key \
-in certificate.crt \
-certfile chain.crt

-legacy is shorthand for the older RC2/3DES ciphers plus a SHA-1 MAC. If your OpenSSL build does not accept -legacy, spell the algorithms out:

openssl pkcs12 -export \
-certpbe PBE-SHA1-3DES \
-keypbe PBE-SHA1-3DES \
-macalg sha1 \
-out certificate.pfx \
-inkey private.key \
-in certificate.crt \
-certfile chain.crt

Setting a friendly name #

Windows certificate stores and Java keystores display the archive’s friendly name, and an unnamed entry is painful to pick out of a list later:

openssl pkcs12 -export \
-out certificate.pfx \
-inkey private.key \
-in certificate.crt \
-certfile chain.crt \
-name "example.com production"

Verify the result #

List what actually ended up in the archive
openssl pkcs12 -info -in certificate.pfx -noout
Expected output
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
Certificate bag
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256

Read the output as a checklist. One Certificate bag per certificate means the chain went in — if you passed a two-certificate chain.crt you should see three bags in total. Exactly one Shrouded Keybag means the private key is present and encrypted. The PBES2, PBKDF2, AES-256-CBC line tells you this is a modern archive, so if you were aiming for -legacy output and see this instead, the flag did not take effect.

Common failures #

Symptom Cause Fix
unable to load private key The key is encrypted and you were not prompted, or it is not PEM Add -passin pass:..., or convert the key to PEM first
No certificate matches private key The .crt and .key are from different key pairs Check whether the key and certificate match
Windows: “The password you entered is incorrect” OpenSSL 3.x AES-256 archive Re-export with -legacy
Error outputting keys and certificates with a PEM chain chain.crt contains something that is not a certificate Strip any private key or text preamble from the chain file

Going the other way #

To unpack a PFX back into PEM files, see convert PFX to PEM.

Frequently asked questions

What is the difference between .pfx and .p12?
Nothing. Both extensions denote a PKCS#12 archive with an identical binary format. Microsoft tooling historically wrote .pfx and most other software writes .p12, but the two are interchangeable and OpenSSL reads either.
Can I create a PFX without a private key?
Yes, use openssl pkcs12 -export -nokeys -in certificate.crt -certfile chain.crt -out bundle.pfx. The result is a certificate-only archive, which is what you want when you are shipping a trust bundle rather than an identity.
Can I create a PFX with no password?
Yes, pass -passout pass: with nothing after the colon. Be aware that many import tools refuse a blank password, and the private key inside the file is then entirely unprotected on disk.
Why does Windows say the PFX password is incorrect when it is not?
This is almost always the OpenSSL 3.x cipher change rather than a wrong password. Re-export with -legacy so the archive uses RC2/3DES, which the older Windows CryptoAPI importer can decrypt.

References