Hi!!
It’s been awhile since I’ve posted something but last week I wrote a small script which I think will be useful to you!
Part of my many tasks where I work is to manage our PKI and in general work with and issue certificates. When issuing certificates (which include the private key) using a Windows PKI you normally export the file in PFX format. This is useful when working with Windows servers or applications. However in Linux servers or applications it’s more common that you need the certificate split into two files e.g. cert.crt/cert.key which separate the public/private keys.
In order to convert/split the PFX file into two files and separate the public/private keys you need to use openssl and manually run specific commands. This can be a bit tricky if you aren’t familiar with openssl and certificates in general.
The script I wrote does this for you automatically and can also optionally convert the private key to PEM format or decrypt the private key so it isn’t password protected (some applications need this). This can save you a lot of time and hopefully make your lives easier 🙂
Prerequisites
You need to install OpenSSL as the script uses this to perform the different actions.
I have built the script in three different sections – Parameters, Initialize and Script Main. To begin with I will quickly explain the Parameters section.
PARAMETERS
#PARAMETERS $openssl = 'C:\OpenSSL-Win64\bin\openssl.exe' $sourcePFX = 'c:\mycert.pfx' $sourcePFX_Passphrase = 'somepassword' $convertToPEM = $true $decryptPrivateKey = $true
$openssl – Path to your openssl.exe here.
$sourcePFX – Path to the PFX you want to connvert/split.
$sourcePFX_Passphrase – password of the $sourcePFX file.
$convertToPEM – Set to $true to convert the private key to PEM format. $false to ignore/not do it.
$decryptPrivateKey – Set to $true to decrypt the private key and remove the password protection (don’t give it out to anyone who’s not supposed to have it after this…). $false to ignore/not do it.
INITIALIZE
$sourcePFX_Dir = (Get-ChildItem $sourcePFX).DirectoryName $PrivateKeyFile = $sourcePFX.Replace('.pfx', '-encrypted.key') $PublicKeyFile = $sourcePFX.Replace('.pfx', '.crt') $ErrorActionPreference = 'SilentlyContinue'
In this section use the parameters given to create some variables I will using in the script main.
$sourcePFX_Dir = (Get-ChildItem $sourcePFX).DirectoryName
Here I get the path of the directory of the source PFX so we can create the new certificates in the same place.
$PrivateKeyFile = $sourcePFX.Replace(‘.pfx’, ‘-encrypted.key’)
$PublicKeyFile = $sourcePFX.Replace(‘.pfx’, ‘.crt’)
Here I create file names of the new certs based on source PFX name.
$ErrorActionPreference = ‘SilentlyContinue’
Here I tell powershell to not display errors when running the script. This is because openssl returns messages that cause powershell to error out (even when it succeeds). This is a bit confusing so I chose to remove the errors displayed. You can remove this if you want as it’s not crucial.
SCRIPT MAIN
The embedded comments in this section should be enough to tell you what I’m doing here. Basically I start with running commands that extract the public and private keys into two new files. Then I add a few if statements that convert the converts to PEM and/or decrypts the private key if you set those params to true earlier.
#SCRIPT MAIN #Extract the private key & $openssl 'pkcs12' -in $sourcePFX -nocerts -out $PrivateKeyFile -password pass:$sourcePFX_Passphrase -passout pass:$sourcePFX_Passphrase #Extract the public key & $openssl pkcs12 -in $sourcePFX -clcerts -nokeys -out $PublicKeyFile -password pass:$sourcePFX_Passphrase #if specified convert private key to PEM if ($convertToPEM) { $PrivateKeyPEMFile = $PrivateKeyFile.Replace('.key', '-pem.key') & $openssl rsa -in $PrivateKeyFile -outform PEM -out $PrivateKeyPEMFile -passin pass:$sourcePFX_Passphrase -passout pass:$sourcePFX_Passphrase } #If specified decrypt the private key if ($decryptPrivateKey) { if ($convertToPEM) { $PrivateKeyFile = $PrivateKeyPEMFile } $decryptedKeyFile = $PrivateKeyFile.Replace('.key', '-decrypted.key').Replace('-encrypted','') & $openssl rsa -in $PrivateKeyFile -out $decryptedKeyFile -passin pass:$sourcePFX_Passphrase -passout pass:$sourcePFX_Passphrase }
That’s it!!
I hope you find the script useful!
I have copied in the full script below for you to copy if needed.
<# .NOTES =========================================================================== Created on: 29-Mar-2017 12:16 PM Created by: Noam Wajnman Filename: Split-PFXCertificate.ps1 =========================================================================== .DESCRIPTION Splits a PFX certificate into a public/private key pair. See the Parameters section to optionally convert to PEM and/or decrypt the private key. #> #PARAMETERS $openssl = 'C:\OpenSSL-Win64\bin\openssl.exe' $sourcePFX = 'c:\mycert.pfx' $sourcePFX_Passphrase = 'somepassword' $convertToPEM = $true $decryptPrivateKey = $true #INITIALIZE $sourcePFX_Dir = (Get-ChildItem $sourcePFX).DirectoryName $PrivateKeyFile = $sourcePFX.Replace('.pfx', '-encrypted.key') $PublicKeyFile = $sourcePFX.Replace('.pfx', '.crt') $ErrorActionPreference = 'SilentlyContinue' #SCRIPT MAIN #Extract the private key & $openssl 'pkcs12' -in $sourcePFX -nocerts -out $PrivateKeyFile -password pass:$sourcePFX_Passphrase -passout pass:$sourcePFX_Passphrase #Extract the public key & $openssl pkcs12 -in $sourcePFX -clcerts -nokeys -out $PublicKeyFile -password pass:$sourcePFX_Passphrase #if specified convert private key to PEM if ($convertToPEM) { $PrivateKeyPEMFile = $PrivateKeyFile.Replace('.key', '-pem.key') & $openssl rsa -in $PrivateKeyFile -outform PEM -out $PrivateKeyPEMFile -passin pass:$sourcePFX_Passphrase -passout pass:$sourcePFX_Passphrase } #If specified decrypt the private key if ($decryptPrivateKey) { if ($convertToPEM) { $PrivateKeyFile = $PrivateKeyPEMFile } $decryptedKeyFile = $PrivateKeyFile.Replace('.key', '-decrypted.key').Replace('-encrypted','') & $openssl rsa -in $PrivateKeyFile -out $decryptedKeyFile -passin pass:$sourcePFX_Passphrase -passout pass:$sourcePFX_Passphrase }