Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
How to convert a .pfx SSL certificate to .crt/key (pem) formats. Useful for NGINX
source: http://www.markbrilman.nl/2011/08/howto-convert-a-pfx-to-a-seperate-key-crt-file/
`openssl pkcs12 -in [yourfile.pfx] -nocerts -out [keyfile-encrypted.key]`
What this command does is extract the private key from the .pfx file. Once entered you need to type in the importpassword of the .pfx file. This is the password that you used to protect your keypair when you created your .pfx file. If you cannot remember it anymore you can just throw your .pfx file away, cause you won’t be able to import it again, anywhere!. Once you entered the import password OpenSSL requests you to type in another password, twice!. This new password will protect your .key file.
Now let’s extract the certificate:
`openssl pkcs12 -in [yourfile.pfx] -clcerts -nokeys -out [certificate.crt]`
Just press enter and your certificate appears.
Now as I mentioned in the intro of this article you sometimes need to have an unencrypted .key file to import on some devices. I probably don’t need to mention that you should be carefully. If you store your unencrypted keypair somewhere on an unsafe location anyone can have a go with it and impersonate for instance a website or a person of your company. So always be extra careful when it comes to private keys! Just throw the unencrypted keyfile away when you’re done with it, saving just the encrypted one.
The command:
`openssl rsa -in [keyfile-encrypted.key] -out [keyfile-decrypted.key]`
Notes:
- When you first extract the key, apply a new password (probably the same as you used to extract it) and then create an unencrypted key with the rsa command above
- Use an encrypted key file for NGINX otherwise it'll ask for the password every time it is restarted.
- Check the top of the extract .crt file for extra bits above the ----BEING... line and remove if necessary
- This certificated needs to be concatenated with the full chain of certificate authorities `cat domain.crt CA_bundle.crt > final.crt`
- test the cert with `openssl s_client -showcerts -connect www.domain.com:443`
@atomicleads

This comment has been minimized.

Copy link

commented Nov 25, 2014

To make this work in nginx i was pushed to do this too:

openssl pkcs12 -in [yourfile.pfx] -out domain-ca.crt -nodes -nokeys -cacerts

and

cat [certificate.crt] domain-ca.crt > [full_certificate.crt]

in nginx i'm using [full_certificate.crt]

@JEinOKC

This comment has been minimized.

Copy link

commented Mar 23, 2016

thanks for this writeup. Followed it step-by-step (as well as atomicleads's additional comment) and it worked perfectly

@apat183

This comment has been minimized.

Copy link

commented Jul 7, 2016

This is awesome! Thumbs UP!

@vikas027

This comment has been minimized.

Copy link

commented Nov 21, 2016

Nice, worked like a breeze. 👍

@anderssonjohan

This comment has been minimized.

Copy link

commented Dec 9, 2016

Thanks, I put together the following script based on this writeup.

#!/bin/bash
# Usage:
# ./createcertfilesfrompfx.sh /path/to/domain.pfx
#
# Creates domain.pem and domain.key in the current directory
#
pfxpath="$1"

if [ ! -f "$pfxpath" ];
then
  echo "Cannot find PFX using path '$pfxpath'"
  exit 1
fi

crtname=`basename ${pfxpath%.*}`
domaincacrtpath=`mktemp`
domaincrtpath=`mktemp`
fullcrtpath=`mktemp`
keypath=`mktemp`
passfilepath=`mktemp`
read -s -p "PFX password: " pfxpass
echo -n $pfxpass > $passfilepath

echo "Creating .CRT file"
openssl pkcs12 -in $pfxpath -out $domaincacrtpath -nodes -nokeys -cacerts -passin file:$passfilepath
openssl pkcs12 -in $pfxpath -out $domaincrtpath -nokeys -clcerts -passin file:$passfilepath
cat $domaincrtpath $domaincacrtpath > $fullcrtpath
rm $domaincrtpath $domaincacrtpath

echo "Creating .KEY file"
openssl pkcs12 -in $pfxpath -nocerts -passin file:$passfilepath -passout pass:Password123 \
| openssl rsa -out $keypath -passin pass:Password123

rm $passfilepath

mv $fullcrtpath ./${crtname}.pem
mv $keypath ./${crtname}.key

ls -l ${crtname}.pem ${crtname}.key
@jawhitti

This comment has been minimized.

Copy link

commented Sep 16, 2017

I tried to do this manually and failed, but anderssonjohan's script worked exactly correctly. A+++ would import certs again.

@bvdeenen

This comment has been minimized.

Copy link

commented Sep 26, 2017

THANKS!

I just aged a year in about 8 hours trying to get all this stuff to work! Your gist saved my life!

@bora89

This comment has been minimized.

Copy link

commented Feb 11, 2018

@anderssonjohan Great job!

@fmad

This comment has been minimized.

Copy link

commented Feb 20, 2018

Thanks @anderssonjohan! Your script did the trick just fine! The problem of doing it manually was using a password for the pem file that was too simple! Wasn't worried about that as I wanted to remove the password anyway but was wondering why it didn't ask the password twice for the PEM file, and when I tried to execute the commands in your file and used a different password, it just worked.

@gettek

This comment has been minimized.

Copy link

commented May 23, 2018

Great Script Thanks! @anderssonjohan

@yarikzub

This comment has been minimized.

Copy link

commented Jun 24, 2018

Thank you @anderssonjohan for script!

@imsurinder90

This comment has been minimized.

Copy link

commented Jun 27, 2018

Thanks a lot for the script. This has saved my day :)

@JasonStein

This comment has been minimized.

Copy link

commented Jul 7, 2018

@anderssonjohan Saved my day!

@andriyfm

This comment has been minimized.

Copy link

commented Sep 29, 2018

hai. everyone, i was follow the tutorial and every ok, when i check usinc curl https://domain.com/.. but when i trying to check into browser the result is page can not be found message. please can you tell me, what the recommend setting for it server block? thanks

@domharrington

This comment has been minimized.

Copy link

commented Oct 23, 2018

To get the private key, i had to run the following command with -nodes as well:

openssl pkcs12 -in [yourfile.pfx] -nocerts -nodes -out [keyfile-encrypted.key]

Without this, the file didnt contain the private key -----BEGIN PRIVATE KEY----- it just contained a file starting with Bag Attributes.

@nunogrl

This comment has been minimized.

Copy link

commented Feb 25, 2019

Thanks for the script!
If the logic is right, I've made some changes on the script as I'm handling too many certificates and the script handles too many temporary folders.
Here's my version (the output is a folder with the domain name with the certs inside)

.
├── pfxpass
├── my-domain-name
│   ├── my-domain-name-ca.crt
│   ├── my-domain-name.crt
│   ├── my-domain-name.key
│   └── my-domain-name.pem
├── my-domain-name (copy 1)
│   ├── my-domain-name (copy 1)-ca.crt
│   ├── my-domain-name (copy 1).crt
│   ├── my-domain-name (copy 1).key
│   └── my-domain-name (copy 1).pem
├── my-domain-name (copy 1).pfx
└── my-domain-name.pfx
CERTSPATH="./"
PASSFILE="./pfxpass"
for FILE in "${CERTSPATH}"*.pfx ; do
    DOMAIN=$(basename -s".pfx" "${FILE}")
    echo "Processing ${DOMAIN}"
    mkdir -p "${DOMAIN}"
    echo " - Creating .CRT file"
    openssl pkcs12 -in "${FILE}" -out "${DOMAIN}"/"${DOMAIN}"-ca.crt -nodes -nokeys -cacerts -passin file:"${PASSFILE}"
    openssl pkcs12 -in "${FILE}" -out "${DOMAIN}"/"${DOMAIN}".crt -nokeys -clcerts -passin file:"${PASSFILE}"
    cat "${DOMAIN}"/"${DOMAIN}"-ca.crt "${DOMAIN}"/"${DOMAIN}".crt > "${DOMAIN}"/"${DOMAIN}".pem
    echo " - Creating .KEY file"
    openssl pkcs12 -in "${FILE}" -nocerts -passin file:"${PASSFILE}" -passout pass:Password123 \
        | openssl rsa -out "${DOMAIN}"/"${DOMAIN}".key -passin pass:Password123
    ls -l "${DOMAIN}/"*.key
    ls -l "${DOMAIN}/"*.pem
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.