How to convert between different security certificate formats

Security certificate formats

There are many variants of these questions, asking how to convert TLS (technically X.509) certificates between various formats. To be stored in a file, a certificate must be encoded. Some common common encodings are:

  • DER (Distinguished Encoding Rules), a binary encoding;
  • PKCS#7 or CMS (Cryptographic Message Syntax), another binary encoding;
  • PEM (Privacy-Enhanced Mail), an ASCII-armouring of binary data to protect it against accidental corruption by systems such as email that only handle text.

A useful convention is for the filename to use an extension that indicates the encoding of the data in it, such as "cert.der" to indicate that the contained certificate is DER-encoded. However it is more common for PEM-encoded certificates to be given a file extension of .crt or .cer. Since PEM can encode other data, such as private keys, it is not uncommon for files to contain multiple PEM-encoded objects. In contrast, a .der file should only contain a single DER-encoded certificate. The PKCS#7/CMS format is very flexible and can contain arbitrary encrypted and/or signed data, but .p7b files contain only certificates, and sometimes certificate revocation lists, in PKCS#7. PKCS#12 or PFX is another format that can contain multiple objects, such as a server private key and the corresponding certificate. Such files have the extension .pfx by convention.

Converting between formats

The most convenient and reliable tool for converting between these different formats is openssl.

  1. Dealing with just a certificate, we can convert between DER, P7B, and PEM encodings as follows:
    $ openssl x509  -in cert.pem  -outform der -out cert.der
    $ openssl x509  -in cert.der -inform der  -out cert.pem
    
    $ openssl pkcs7 -print_certs -in cert.p7b -out cert.pem
    $ openssl crl2pkcs7 -nocrl -certfile cert.pem  -out cert.p7b
    If you take a look at the .p7b file created by this last command, you'll see that it is base-64 encoded data with a BEGIN/END header/trailer. It is actually the certificate encoded twice, first in PKCS#7/CMS and then in PEM, just as the regular .pem format is actually DER encoded in PEM.
  2. To create PFX file containing both a server private key and a certificate, we can must provide both parts, and optionally the CA (Certificate Authority) certificate we used to sign our certificate:
    $ openssl pkcs12 -export -out cert.pfx -inkey key.pem -in cert.pem -certfile CA-cert.pem
    
    We can also extract the certificate from a PFX file:
       $ openssl pkcs12 -in cert.pfx -out cert.pem -nokeys
    
  3. We can also create an equivalent PEM file containing the same content for use by a webserver such as Apache by simply concatenating the .pem files:
    $ cat cert.pem key.pem >server.pem
    
    Again we can extract the certificate with openssl:
    $ openssl x509 -in server.pem -out cert.pem