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.
The command #
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
| Placeholder | What to put there |
|---|---|
certificate.pfx | The PKCS#12 file to create. .p12 is the same format. |
private.key | PEM private key that matches the certificate. |
certificate.crt | The end-entity (server) certificate, PEM-encoded. |
chain.crt | Intermediate 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:
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.
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 #
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
.pfxand 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
-legacyso the archive uses RC2/3DES, which the older Windows CryptoAPI importer can decrypt.
References
- openssl-pkcs12(1) — -export and the -legacy flag
- RFC 7292: PKCS #12 — the archive format, including the MAC OpenSSL 3 rejects on legacy files