Private keys and certificates can be stored in a variety of formats, which means that you’ll often need to convert them from one format to another. The most common formats are:
- Binary (DER) certificate
Contains an X.509 certificate in its raw form, using DER ASN.1 encoding.
- ASCII (PEM) certificate(s)
Contains a base64-encoded DER certificate, with
-----BEGIN CERTIFICATE-----used as the header and
-----END CERTIFICATE-----as the footer. Usually seen with only one certificate per file, although some programs allow more than one certificate depending on the context. For example, older Apache web server versions require the server certificate to be alone in one file, with all intermediate certificates together in another.
- Legacy OpenSSL key format
Contains a private key in its raw form, using DER ASN.1 encoding. Historically, OpenSSL used a format based on PKCS #1. These days, if you use the proper commands (i.e.,
genpkey), OpenSSL defaults to PKCS #8.
- ASCII (PEM) key
Contains a base64-encoded DER key, sometimes with additional metadata (e.g., the algorithm used for password protection). The text in the header and footer can differ, depending on what underlying key format is used.
- PKCS #7 certificate(s)
A complex format designed for the transport of signed or encrypted data, defined in RFC 2315. It’s usually seen with
.p7cextensions and can include the entire certificate chain as needed. This format is supported by Java’s
- PKCS #8 key
The new default format for the private key store. PKCS #8 is defined in RFC 5208. Should you need to convert from PKCS #8 to the legacy format for whatever reason, use the
- PKCS #12 (PFX) key and certificate(s)
A complex format that can store and protect a server key along with an entire certificate chain. It’s commonly seen with
.pfxextensions. This format is commonly used in Microsoft products, but is also used for client certificates. These days, the PFX name is used as a synonym for PKCS #12, even though PFX referred to a different format a long time ago (an early version of PKCS #12). It’s unlikely that you’ll encounter the old version anywhere.
Certificate conversion between PEM and DER formats is performed with the
x509 tool. To convert a certificate from PEM to DER format:
$ openssl x509 -inform PEM -in fd.pem -outform DER -out fd.der
To convert a certificate from DER to PEM format:
$ openssl x509 -inform DER -in fd.der -outform PEM -out fd.pem
The syntax is identical if you need to convert private keys between DER and PEM formats, but different commands are used:
rsa for RSA keys, and
dsa for DSA keys. If you’re dealing with the new PKCS #8 format, use the
One command is all that’s needed to convert the key and certificates in PEM format to PKCS #12. The following example converts a key (
fd.key), certificate (
fd.crt), and intermediate certificates (
fd-chain.crt) into an equivalent single PKCS #12 file:
$ openssl pkcs12 -export \ -name "My Certificate" \ -out fd.p12 \ -inkey fd.key \ -in fd.crt \ -certfile fd-chain.crt Enter Export Password: **************** Verifying - Enter Export Password: ****************
The reverse conversion isn’t as straightforward. You can use a single command, but in that case you’ll get the entire contents in a single file:
$ openssl pkcs12 -in fd.p12 -out fd.pem -nodes
Now, you must open the file
fd.pem in your favorite editor and manually split it into individual key, certificate, and intermediate certificate files. While you’re doing that, you’ll notice additional content provided before each component. For example:
Bag Attributes localKeyID: E3 11 E4 F1 2C ED 11 66 41 1B B8 83 35 D2 DD 07 FC DE 28 76 subject=/220.127.116.11.4.1.318.104.22.168.3=GB/22.214.171.124=Private Organization/serialNumber=06694169/C=GB/ST=London/L=London/O=Feisty Duck Ltd/CN=www.feistyduck.com issuer=/C=US/ST=Arizona/L=Scottsdale/O=Starfield Technologies, Inc./OU=http://certificates.starfieldtech.com/repository/CN=Starfield Secure Certification Authority -----BEGIN CERTIFICATE----- MIIF5zCCBM+gAwIBAgIHBG9JXlv9vTANBgkqhkiG9w0BAQUFADCB3DELMAkGA1UE BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAj [...]
This additional metadata is very handy to quickly identify the certificates. Obviously, you should ensure that the main certificate file contains the leaf server certificate and not something else. Further, you should also ensure that the intermediate certificates are provided in the correct order, with the issuing certificate following the signed one. If you see a self-signed root certificate, feel free to delete it or store it elsewhere; it shouldn’t go into the chain.
The final conversion output shouldn’t contain anything apart from the encoded key and certificates. Although some tools are smart enough to ignore what isn’t needed, other tools are not. Leaving extra data in PEM files might result in problems that are difficult to troubleshoot.
It’s possible to get OpenSSL to split the components for you, but doing so requires multiple invocations of the
pkcs12 command (including typing the bundle password each time):
$ openssl pkcs12 -in fd.p12 -nocerts -out fd.key -nodes $ openssl pkcs12 -in fd.p12 -nokeys -clcerts -out fd.crt $ openssl pkcs12 -in fd.p12 -nokeys -cacerts -out fd-chain.crt
This approach won’t save you much work. You must still examine each file to ensure that it contains the correct contents and to remove the metadata.
To convert from PEM to PKCS #7, use the
$ openssl crl2pkcs7 -nocrl -out fd.p7b -certfile fd.crt -certfile fd-chain.crt
To convert from PKCS #7 to PEM, use the
pkcs7 command with the
openssl pkcs7 -in fd.p7b -print_certs -out fd.pem
Similar to the conversion from PKCS #12, you must now edit the
fd.pem file to clean it up and split it into the desired components.