Bridge SSL

Export and import a certificate with its private key

9 min readUpdated

To export and import a certificate between servers, move it together with its private key. On Windows the pair travels as a PFX file, the PKCS #12 format defined in RFC 7292: a transfer syntax for private keys and certificates that can protect them with a password [1]. You export the SSL certificate on the server that holds the key and import it on the new one; what each server needs after that is covered in installing SSL certificates.

One condition decides whether this works: the key has to be exportable. Servers such as nginx and Apache read PEM files instead of a PFX, and OpenSSL converts between the two in both directions [5].

File
PFX (PKCS #12): the certificate, its private key and, if you include it, the chain [1] [2]
Export on Windows
certlm.msc, certutil -exportPFX or Export-PfxCertificate [2] [6] [7]
Import on Windows
certlm.msc, certutil -importPFX or Import-PfxCertificate [3] [6] [8]
Condition
the private key is marked as exportable [2]
To and from PEM
openssl pkcs12 [5]

Can the key be exported?

Check this first, on the server where the certificate is installed. In the export wizard, Yes, export the private key appears only if the key is marked as exportable and you have access to it [2]. Microsoft states that a key is exportable only when the certificate request or template asked for it [2]. On import, each tool sets the same flag in its own way:

Whether the private key stays exportable after each way of putting it on a server
Where the key came fromExportable afterwards
Certificate request or templateonly if the request or template specified it [2]
Certificate Import Wizardonly with Mark key as exportable selected [3]
Import-PfxCertificateonly with -Exportable [8]
certutil -importPFXnon-exportable with the NoExport modifier [6]

If the key is locked, the wizard does not offer the option [2], and Microsoft's example for exporting a whole store needs every key in it to be exportable [7]. Request a new certificate on the target server instead. Which request tools on IIS let you mark the key exportable is covered where you generate a CSR in IIS.

Export a PFX on Windows

Exporting an SSL certificate issued to a computer takes an administrator, or a user given the right permissions [2]. On IIS a server certificate sits in the Local Computer store. certlm.msc opens that store; certmgr.msc opens the Current User store of your own account [4].

Certificates console, certutil and PowerShell compared: export, chain and key encryption
AttributeCertificates consolecertutilPowerShell
ExportAll Tasks, Export [2]-exportPFX [6]Export-PfxCertificate [7]
Chaina checkbox in the wizard [2]NoChain leaves it out, NoRoot only the root [6]included unless -ChainOption EndEntityCertOnly [7]
Key encryptionnot among the documented steps [2]CryptoAlgorithm= TripleDES-Sha1 or Aes256-Sha256 [6]TripleDES_SHA1 by default, or AES256_SHA256 [7]

In the Certificates console

  1. Run certlm.msc [4], expand Personal and select Certificates [2].

  2. Select the certificate. On the Action menu, point to All Tasks and click Export [2].

  3. Choose Yes, export the private key. If the option is missing, the key is not exportable or you cannot access it [2].

  4. Select Include all certificates in the certification path if possible. Leave Delete the private key if the export is successful cleared [2].

  5. Type a password twice, then a path for the .pfx file, and click Finish [2].

The certificate stays in the store after the export. Microsoft documents this wizard for Windows 7 and Windows Server 2008 R2. Strong protection is on by default and is not compatible with some programs; for a key you will use with one of them, clear Enable strong protection [2].

With PowerShell or certutil

Run PowerShell as an administrator. As in Microsoft's example, the identifier at the end of the path selects one certificate; without it, the command takes every certificate in the store [7]:

$password = Read-Host -AsSecureString
Get-ChildItem -Path Cert:\LocalMachine\My\5F98EBBFE735CDDAE00E33E0FD69050EF9220254 |
  Export-PfxCertificate -FilePath C:\certs\example.com.pfx -Password $password

Read-Host -AsSecureString shows asterisks while you type and returns a SecureString, the type -Password takes [9] [7]. Export-PfxCertificate includes the whole chain and the extended properties, and encrypts the private key with TripleDES_SHA1 unless you pass -CryptoAlgorithmOption AES256_SHA256 [7].

certutil accepts the subject common name as the certificate ID. A name can match more than one certificate; a SHA-1 certificate hash is another accepted ID [6]:

certutil -p <password> -exportPFX My example.com C:\certs\example.com.pfx

certutil works on the machine certificate store; -user switches it to your own [6].

Import the PFX on the target server

Copy the file to the new server. Importing certificates for a web server means the Local Computer store, not your own.

  1. In certlm.msc, select Personal. On the Action menu, point to All Tasks and click Import [3].

  2. Select the .pfx file and type its password [3].

  3. Select Mark key as exportable only if you will move or back up this key again [3].

  4. Choose Place all certificates in the following store and pick Personal, or let the wizard select the store by certificate type [3].

The wizard also offers Enable strong private key protection, which prompts for a password every time the private key is used [3].

The same import in PowerShell:

$password = Read-Host -AsSecureString
Import-PfxCertificate -FilePath C:\certs\example.com.pfx -CertStoreLocation Cert:\LocalMachine\My -Password $password

The key arrives non-exportable unless you add -Exportable [8]. With certutil, certutil -p <password> -importPFX My C:\certs\example.com.pfx NoExport does the same and keeps the key locked [6]. The PFX file stays where it was after the import [3]; delete it once it is no longer needed. Binding the imported certificate to a site is the next step for an SSL certificate on IIS.

PFX to PEM files for nginx or Apache

To take a certificate from Windows to Linux, split the PFX into three PEM files: the certificate, its intermediates and the key:

$ openssl pkcs12 -in example.com.pfx -clcerts -nokeys -out example.com.crt
$ openssl pkcs12 -in example.com.pfx -cacerts -nokeys -out intermediate.crt
$ openssl pkcs12 -in example.com.pfx -nocerts -noenc -out example.com.key

Each command asks for the import password. -clcerts writes only the certificate that belongs to the private key. Without it, OpenSSL writes every certificate in file order, and nothing guarantees the first one is the key's [5]. -cacerts writes the CA certificates, here the intermediate. -noenc writes the key without encryption; it replaces -nodes, deprecated since OpenSSL 3.0 [5]. Protect example.com.key as you would the PFX.

Each output file opens with Bag Attributes lines above the -----BEGIN line; for the certificate and the key they hold the local key ID and the friendly name. RFC 7468 permits text before that line and requires parsers to handle it [10]. Where the files go next depends on the server: see how to install an SSL certificate on Apache or install an SSL certificate on nginx. The certificate formats themselves are explained in the formats guide of the certificates section.

PEM files to a PFX for Windows

For the other direction, assemble the three PEM files into one PFX. -inkey takes the private key [5]:

$ openssl pkcs12 -export -out example.com.pfx -inkey example.com.key -in example.com.crt -certfile intermediate.crt -name example.com
Enter Export Password:
Verifying - Enter Export Password:

-certfile adds the intermediate, and -name sets the friendly name that importing software shows [5]. Import the result into the certificate store as described above.

Which algorithms the file uses

OpenSSL 3.0 encrypts the key and the certificates with AES-256-CBC and PBKDF2 by default. -info shows the algorithms and iteration counts a file uses [5]; on Windows, certutil -dumpPFX dumps its structure [6]. On the lab file built above:

$ openssl pkcs12 -in example.com.pfx -info -noout
Enter Import Password:
MAC: sha256, Iteration 2048
MAC length: 32, salt length: 8
PKCS7 Encrypted data: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256
Certificate bag
Certificate bag
PKCS7 Data
Shrouded Keybag: PBES2, PBKDF2, AES-256-CBC, Iteration 2048, PRF hmacWithSHA256

The two certificate bags are the certificate and the intermediate; the shrouded keybag is the private key, encrypted [1]. With -legacy, OpenSSL uses the legacy algorithms instead: 3DES for the key, RC2 or 3DES for the certificates, depending on the build [5].

A file with RC2-40 certificate encryption, like the lab's -legacy file, fails in OpenSSL 3.0 without the flag:

$ openssl pkcs12 -in legacy.pfx -info -noout
Enter Import Password:
MAC: sha1, Iteration 2048
MAC length: 20, salt length: 8
PKCS7 Encrypted data: pbeWithSHA1And40BitRC2-CBC, Iteration 2048
Error outputting keys and certificates
40A73845A8720000:error:0308010C:digital envelope routines:inner_evp_generic_fetch:unsupported:../crypto/evp/evp_fetch.c:386:Global default library context, Algorithm (RC2-40-CBC : 0), Properties ()

With -legacy the same command reads it, as the manual advises for RC2-40-CBC [5].

Common mistakes

  • No key option in the wizard. The key is not exportable, or your account cannot access it [2].

  • Key deleted on export. Delete the private key if the export is successful removes the key from the source server [2].

  • Chain left out. Without Include all certificates in the certification path, the intermediates are not included [2]; -ChainOption EndEntityCertOnly and NoChain drop them on purpose [7] [6].

  • Wrong store. certmgr.msc and Cert:\CurrentUser\My belong to one user account [4] [8].

  • Files left behind. The PFX stays on disk after import [3], and the key from -noenc has no password at all [5].

FAQ

How do I create a PFX file from a CRT and a key?

Run openssl pkcs12 -export -out example.com.pfx -inkey example.com.key -in example.com.crt -certfile intermediate.crt and set an export password.

How do I extract the private key from a PFX file?

Run openssl pkcs12 -in example.com.pfx -nocerts -noenc -out example.com.key. The key is written without a password.

How do I get a PFX file from a Windows server?

Export the certificate with its private key in certlm.msc or with Export-PfxCertificate, on the server that holds the key. This works only if the key is exportable.

Sources

  1. IETF, RFC 7292, PKCS #12: Personal Information Exchange Syntax v1.1.

  2. Microsoft Learn, Export a Certificate with the Private Key: exportable keys, wizard options.

  3. Microsoft Learn, Import a Certificate: Mark key as exportable, store selection.

  4. Microsoft Learn, How to: View certificates with the MMC snap-in.

  5. OpenSSL, openssl-pkcs12 manual page, version 3.0.

  6. Microsoft Learn, certutil: -exportPFX, -importPFX.

  7. Microsoft Learn, Export-PfxCertificate.

  8. Microsoft Learn, Import-PfxCertificate.

  9. Microsoft Learn, Read-Host.

  10. IETF, RFC 7468, Textual Encodings of PKIX, PKCS, and CMS Structures, section 2.