1.2.10 Key and Certificate Conversion
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
.p7b
and.p7c
extensions and can include the entire certificate chain as needed. This format is supported by Java’skeytool
utility. - 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
pkcs8
command. - 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
.p12
and.pfx
extensions. 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.
1.2.10.1 PEM and DER Conversion
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 pkey
tool.
1.2.10.2 PKCS #12 (PFX) Conversion
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=/1.3.6.1.4.1.311.60.2.1.3=GB/2.5.4.15=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.
1.2.10.3 PKCS #7 Conversion
To convert from PEM to PKCS #7, use the crl2pkcs7
command:
$ 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 -print_certs
switch:
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.