Extract public/private key from PKCS12 file for later use in SSH-PK-Authentication

You can use following commands to extract public/private key from a PKCS#12 container:

  • PKCS#1 Private key

    openssl pkcs12 -in yourP12File.pfx -nocerts -out privateKey.pem
    
  • Certificates:

    openssl pkcs12 -in yourP12File.pfx -clcerts -nokeys -out publicCert.pem
    

This is possible with a bit of format conversion.

To extract the private key in a format openssh can use:

openssl pkcs12 -in pkcs12.pfx -nocerts -nodes | openssl rsa > id_rsa

To convert the private key to a public key:

openssl rsa -in id_rsa -pubout | ssh-keygen -f /dev/stdin -i -m PKCS8

To extract the public key in a format openssh can use:

openssl pkcs12 -in pkcs12.pfx -clcerts -nokeys | openssl x509 -pubkey -noout | ssh-keygen -f /dev/stdin -i -m PKCS8

OpenSSH cannot use PKCS#12 files out of the box. As others suggested, you must extract the private key in PEM format which gets you from the land of OpenSSL to OpenSSH. Other solutions mentioned here don’t work for me. I use OS X 10.9 Mavericks (10.9.3 at the moment) with “prepackaged” utilities (OpenSSL 0.9.8y, OpenSSH 6.2p2).

First, extract a private key in PEM format which will be used directly by OpenSSH:

openssl pkcs12 -in filename.p12 -clcerts -nodes -nocerts | openssl rsa > ~/.ssh/id_rsa

I strongly suggest to encrypt the private key with password:

openssl pkcs12 -in filename.p12 -clcerts -nodes -nocerts | openssl rsa -passout 'pass:Passw0rd!' > ~/.ssh/id_rsa

Obviously, writing a plain-text password on command-line is not safe either, so you should delete the last command from history or just make sure it doesn’t get there. Different shells have different ways. You can prefix your command with space to prevent it from being saved to history in Bash and many other shells. Here is also how to delete the command from history in Bash:

history -d $(history | tail -n 2 | awk 'NR == 1 { print $1 }')

Alternatively, you can use different way to pass a private key password to OpenSSL - consult OpenSSL documentation for pass phrase arguments.

Then, create an OpenSSH public key which can be added to authorized_keys file:

ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub