Extract the private key from a PFX / P12

To extract just the private key from a PFX, run `openssl pkcs12 -in certificate.pfx -nocerts -nodes -out private.key`. `-nocerts` suppresses the certificates and `-nodes` writes the key unencrypted, which is what a web server needs. The output contains PKCS#12 bag attributes above the key; they are harmless, but `openssl pkey -in private.key -out private-clean.key` re-emits just the key if you want a tidy file. If OpenSSL 3 refuses the archive, add `-legacy`.

Updated August 19, 2026 Verified against OpenSSL 3.5.7

Check the archive first #

openssl pkcs12 -in certificate.pfx -info -noout
Expected output
MAC: sha256, Iteration 2048
Certificate bag
Certificate bag
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC

A Shrouded Keybag line means there is a private key to extract. If there is none, the archive was exported certificates-only and there is nothing to get.

Extract the key #

Unencrypted, ready for a web server
openssl pkcs12 -in certificate.pfx -nocerts -nodes -out private.key
chmod 600 private.key

Replace these values

PlaceholderWhat to put there
-nocertsSuppress the certificates, leaving only the key.
-nodesWrite the key unencrypted. Spelled -noenc in OpenSSL 3.
private.keyOutput. Contains bag attributes above the PEM block.

Keeping the key encrypted #

Prompts for a new passphrase
openssl pkcs12 -in certificate.pfx -nocerts -out private.key

Stripping the bag attributes #

The extracted file looks like this:

Bag Attributes
  friendlyName: example.com
  localKeyID: A1 B2 C3 D4 ...
Key Attributes: <No Attributes>
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcw...
-----END PRIVATE KEY-----

Every parser ignores what is outside the markers, so this works. To normalise it anyway:

openssl pkey -in private.key -out private-clean.key

Non-interactive extraction #

openssl pkcs12 -in certificate.pfx -nocerts -nodes \
-passin file:/run/secrets/pfx-password \
-out private.key

If OpenSSL 3 refuses the file #

openssl pkcs12 -legacy -in certificate.pfx -nocerts -nodes -out private.key

Older tools wrote archives using RC2 or 3DES, which OpenSSL 3 moved into a provider that is not loaded by default. The resulting error usually mentions the MAC or reads like a wrong password.

Confirm the key matches the certificate #

Extract the certificate too and check they belong together before deploying:

openssl pkcs12 -in certificate.pfx -clcerts -nokeys -out certificate.crt
openssl pkey -in private.key -pubout | openssl sha256
openssl x509 -in certificate.crt -noout -pubkey | openssl sha256

They came from the same archive so they should match — but checking costs a second and catches the case where you extracted from the wrong file.

Frequently asked questions

Why does the output have "Bag Attributes" text above the key?
OpenSSL writes the PKCS#12 metadata — friendly name and local key ID — alongside the extracted object. Every parser ignores anything outside the BEGIN/END markers, so the file works as-is. Re-emit through openssl pkey if you want it clean.
Can I extract without the password?
No. The key inside the archive is encrypted with a key derived from the import password, and there is no way around it.
How do I get an encrypted key out instead?
Omit -nodes. OpenSSL then prompts for a new passphrase and writes an encrypted PKCS#8 key. Useful when the key is going somewhere a person will handle it rather than a service.
Is there a Shrouded Keybag but extraction still fails?
The archive probably uses legacy algorithms OpenSSL 3 does not load by default. Add -legacy. See that error explained.

References