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

I want to extract the public and private key from my PKCS#12 file for later use in SSH-Public-Key-Authentication.

Right now, I'm generating keys via ssh-keygen which I put into .ssh/authorized_key, respective somewhere on the client-side.

In future, I want to use the keys from a PKCS#12 container, so I've to extract the public-key first from PKCS#12 and then put them into the .ssh/authorized_keys file. Is there any chance to get this working via openssl? Are the keys in PKCS#12 compatible for ssh-public-key authentication?

This question is related to ssh openssl certificate x509 pkcs#12

The answer is


Solution 1:

Extract P12 from jks

keytool -importkeystore -srckeystore MyRootCA.jks -destkeystore MyRootCA.p12 -deststoretype PKCS12

Extract PEM from P12 and Edit file and pem from crt file

openssl pkcs12 -in MyRootCA.p12 -clcerts -nokeys -out MyRootCA.crt

Extract key from jks

openssl pkcs12 -in MyRootCA.p12 -nocerts -out encryptedPrivateKey.pem
openssl rsa -in encryptedPrivateKey.pem -out decryptedPrivateKey.key

Solution 2:

Extract PEM and encryptedPrivateKey to txt file```

openssl pkcs12 -in MyRootCA.p12 -out keys_out.txt

Decrypt privateKey

openssl rsa -in encryptedPrivateKey.key [-outform PEM] -out decryptedPrivateKey.key

As far as I know PKCS#12 is just a certificate/public/private key store. If you extracted a public key from PKCS#12 file, OpenSSH should be able to use it as long as it was extracted in PEM format. You probably already know that you also need a corresponding private key (also in PEM) in order to use it for ssh-public-key authentication.


Update: I noticed that my answer was just a poor duplicate of a well explained question on https://unix.stackexchange.com/... by BryKKan

Here is an extract from it:

openssl pkcs12 -in <filename.pfx> -nocerts -nodes | sed -ne '/-BEGIN PRIVATE KEY-/,/-END PRIVATE KEY-/p' > <clientcert.key>

openssl pkcs12 -in <filename.pfx> -clcerts -nokeys | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > <clientcert.cer>

openssl pkcs12 -in <filename.pfx> -cacerts -nokeys -chain | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > <cacerts.cer>

The accepted answer is the correct command, I just want to add one additional thing, when extracting the key if you leave the PEM password("Enter PEM pass phrase:") blank then the complete key will not be extracted but only the localKeyID will be extracted. To get the complete key you must specify a PEM password whem running the following command.

Please note that when it comes to Import password, you can specify the actual password for "Enter Import Password:" or can leave this password blank:

openssl pkcs12 -in yourP12File.pfx -nocerts -out privateKey.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

Examples related to ssh

Starting ssh-agent on Windows 10 fails: "unable to start ssh-agent service, error :1058" How to solve "sign_and_send_pubkey: signing failed: agent refused operation"? key_load_public: invalid format ssh connection refused on Raspberry Pi Getting permission denied (public key) on gitlab Verify host key with pysftp Can't connect to Postgresql on port 5432 Checkout Jenkins Pipeline Git SCM with credentials? How to open remote files in sublime text 3 how to setup ssh keys for jenkins to publish via ssh

Examples related to openssl

dyld: Library not loaded: /usr/local/opt/openssl/lib/libssl.1.0.0.dylib How to install OpenSSL in windows 10? SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 How to fix: fatal error: openssl/opensslv.h: No such file or directory in RedHat 7 Homebrew refusing to link OpenSSL Solving sslv3 alert handshake failure when trying to use a client certificate How to install latest version of openssl Mac OS X El Capitan How to resolve the "EVP_DecryptFInal_ex: bad decrypt" during file decryption SSL error SSL3_GET_SERVER_CERTIFICATE:certificate verify failed Can't get private key with openssl (no start line:pem_lib.c:703:Expecting: ANY PRIVATE KEY)

Examples related to certificate

Distribution certificate / private key not installed When you use 'badidea' or 'thisisunsafe' to bypass a Chrome certificate/HSTS error, does it only apply for the current site? Cannot install signed apk to device manually, got error "App not installed" Using client certificate in Curl command Convert .cer certificate to .jks SSL cert "err_cert_authority_invalid" on mobile chrome only Android Studio - Unable to find valid certification path to requested target SSL: error:0B080074:x509 certificate routines:X509_check_private_key:key values mismatch Verify a certificate chain using openssl verify Import Certificate to Trusted Root but not to Personal [Command Line]

Examples related to x509

How can I generate a self-signed certificate with SubjectAltName using OpenSSL? How to read .pem file to get private and public key Extract public/private key from PKCS12 file for later use in SSH-PK-Authentication Getting RSA private key from PEM BASE64 Encoded private key file How to convert .crt to .pem Using HTTPS with REST in Java What does "subject" mean in certificate? CryptographicException 'Keyset does not exist', but only through WCF

Examples related to pkcs#12

Creating a .p12 file Converting PKCS#12 certificate into PEM using OpenSSL How to list the certificates stored in a PKCS12 keystore with keytool? Extract public/private key from PKCS12 file for later use in SSH-PK-Authentication