I have a PKCS #12 file and want to export certificates and private key from the PKCS #12 file with openssl.

openssl pkcs12 -in test.p12 -nocerts -out key.pem
openssl pkcs12 -in test.p12 -out certs.pem -nokeys -nodes

I want to uncrypt the key file

openssl rsa -in key.pem -out uncrypt_key.pem

But if I want to validate the cert key pair it fails.

openssl openssl x509 -noout -modulus -in certs.pem | openssl md5
openssl rsa -noout -modulus -in uncrypt_key.pem | openssl md5

Also the public key diff with der public keys fails.

openssl x509 -in certs.pem -pubkey -noout > certs.pub
openssl rsa -in uncrypt_key.pem -pubout > uncrypt_key.pub
diff certs.pub uncrypt_key.pub

How could I solve this problem or what is my mistake.


PKCS12 is a very flexible format and technically can contain almost any combination of privatekeys and/or certificates, and some other things as well. Usually it is used to contain one privatekey and the certificate chain for that privatekey -- i.e. one 'end-entity' (EE) certificate for that key and its owner, plus one or more 'chain' certificates for the CA hierarchy used to issue -- and to verify -- the EE cert. But other combinations are possible.

If you look at your certs.pem file you will almost certainly find more than one certificate in PEM format, each with the subject and issuer noted in human-readable text, as well as any 'bag' attributes, and almost certainly the first cert in the file is not the EE cert for your privatekey (or one of them) -- also check your keys.pem file to see if there is more than one privatekey, which is rare but possible. When a PEM file contains more than one cert, openssl x509 processes only the first one and ignores the rest.

If there is only one privatekey, you can identify its cert by looking at the subject name, and possibly issuer name, as well as the 'localKeyID' and maybe 'friendlyName' bag attribute which will match the privatekey in keys.pem (but not uncrypt_keys.pem, because that process removes the non-PEM 'comment' information); put that cert in a file and process it with x509 -modulus and/or x509 -pubkey. Alternatively you can have openssl pkcs12 extract only the EE cert using the slightly-misnamed -clcerts option on your second command.

If there is more than one privatekey, you must identify the correct key and correct cert by 'localKeyID' and/or 'friendlyName' and isolate them in files; openssl pkcs12 cannot select among them for you. openssl rsa similarly processes only the first key in a PEM file than contains multiple keys. But you can if you want put both cert and key in one file: openssl x509 will process the cert, ignoring the key, while openssl rsa will process the key, ignoring the cert.

PS: if you want the privatekey 'uncrypted' (we usually say 'unencrypted', or more simply but jargonly 'clear[text]' or 'plain[text]', but your meaning is clear enough, pardon the pun) you don't need a separate step, just do openssl pkcs12 -in p12file -out keyfile -nocerts -nodes. For modern versions of OpenSSL (since 2010) this will produce a 'new' (since 2000!) PKCS8-format PEM file instead of the traditional/legacy format produced by the rsa command; for anything using actual OpenSSL this doesn't matter (both formats are always accepted equally) but for some other programs that were written back in the 1990s and never updated it can be a problem. OTOH using -nodes with -nokeys as you did on your second command is ignored and useless, because cert output is never encrypted.

  • Thank you very much for the good explanation. I like also the good style recommondations! – ikreb Nov 10 '20 at 16:07

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.