Convert PEM or DER format certificate files with openssl

Main picture of the post: Convert PEM or DER format certificate files with openssl

This post will show how to convert certificates or keys between the 2 possible formats available for this kind of files with openssl: PEM or DER. But, before jumping in, let’s explain what PEM or DER stands for.

What is PEM format?

PEM means Privacy-Enhanced Mail and it is the most used format when it comes to save certificates or keys as files due to it’s text based data. PEM format it’s mainly based in base64 codification surrounded by the header “—–BEGIN CERTIFICATE—–” and the footer “—–END CERTIFICATE—–” to delimitate the file content. There’s no particular file extension for this format and could be one of “.crt”, “.cer”, “.pem”, “.key”, “.csr”. The advantage that PEM has over the DER format is that it can be transferred or copied without any issues.

What is DER format?

DER stands for Distinguished Encoding Rules and unlike the PEM format, it is a binary based file format for ASN.1 data structures. Despite the PEM format is preferred over the DER format, there are applications that only accepts DER format, so it is good for you to know that this could happen when handling key or certificates files.

Convert different cryptography files to DER format

The way to use openssl to produce a one format or another is with “-outform” option followed with the desired PEM or DER format.

In order to generate a key with DER format, you may first create it with PEM format and then run openssl to copy the key but with DER format.

In the next example, a new private key is generated with the default PEM format, then the private key it is changed to DER format (-outform DER). To verify the output in this use case and others explained in this section, the file command is executed to know what is the kind of content generated:

$ openssl genrsa -out private.key 4096
Generating RSA private key, 4096 bit long modulus
................................................................................................................................................................++
......................++
e is 65537 (0x10001)
$ openssl rsa -in private.key -out private.key.der -outform DER
writing RSA key
$ file private.key
private.key: PEM RSA private key
$ file private.key.der 
private.key.der: data

PKCS7 or p7b, also known as Cryptographic Message Syntax (CMS), is a kind of file that stores signed or encrypted data like certificates or CRLs, no matter they are part of the same chain of trust or independent certificates, but it cannot store private keys (That’s something that PKCS12 covers).

In the next block, it will show the preparation of a simple PKCS7 file with 2 self-signed certificates and then convert it from PEM format to DER:

$ openssl req -x509 -newkey rsa:4096 -keyout private1.key -out cert1.crt -nodes -sha256 -subj '/CN=fse'
Generating a 4096 bit RSA private key
................................................................................................................................................................................................................................................................................................................++
......................................................................................++
writing new private key to 'private1.key'
-----
$ openssl req -x509 -newkey rsa:4096 -keyout private2.key -out cert2.crt -nodes -sha256 -subj '/CN=fse2'
Generating a 4096 bit RSA private key
.............................................................................................++
................................................................................................++
writing new private key to 'private2.key'
-----
$ openssl crl2pkcs7 -nocrl -certfile cert1.crt -certfile cert2.crt -out certs.p7b
$ file certs.p7b
certificates.p7b: ASCII text
$ head -n 5 certs.p7b
-----BEGIN PKCS7-----
MIIKFQYJKoZIhvcNAQcCoIIKBjCCCgICAQExADALBgkqhkiG9w0BBwGgggnoMIIE
7zCCAtegAwIBAgIJAL0LIrS/IW/iMA0GCSqGSIb3DQEBCwUAMA4xDDAKBgNVBAMM
A2ZzZTAeFw0yMjA2MDYyMjMzNDZaFw0yMjA3MDYyMjMzNDZaMA4xDDAKBgNVBAMM
A2ZzZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKLlfXJPd5aiRI6f
$ openssl pkcs7 -in certs.p7b -inform PEM -out certs.der.p7b -outform DER
$ file certs.der.p7b
certs.der.p7b: data

The same conversion can be done with a CSR (Certificate Signing Request or PKCS10) file. To show you how this operation can be performed with openssl, a new CSR is generated from the creation of a private key and, afterwards, the CSR format is changed to DER:

$ openssl req -newkey rsa:4096 -keyout private.key -out req.csr -nodes -subj '/CN=fse,/OU=test'
Generating a 4096 bit RSA private key
...................................................................................................................................................++
..................................................................................................++
writing new private key to 'private.key'
-----
$ file req.csr
req.csr: PEM certificate request
$ openssl req -inform PEM -in req.csr -outform DER -out req.der.csr
$ file req.der.csr
req.der.csr: data

Moreover, a certificate can be changed to DER format. In order to show this conversion, a self-signed certificate is created and then, this certificate is converted to DER data type:

$ openssl req -x509 -newkey rsa:4096 -keyout private.key -out cert.crt -nodes -sha256 -subj '/CN=fse'
Generating a 4096 bit RSA private key
.................................++
......++
writing new private key to 'private.key'
-----
$ file cert.crt 
cert.crt: PEM certificate
$ openssl x509 -in cert.crt -inform PEM -out cert.der.crt -outform DER
$ file cert.der.crt
cert.der.crt: data

In the following example, a transformation from PEM to DER format of a PKCS8 is performed. The options are similar to previous use cases, but a “-nocrypt” option is issued in order to tell openssl to handle the PKCS8 key files without encryption:

$ openssl genrsa -out private.key 4096
Generating RSA private key, 4096 bit long modulus
...............................................................................++
...........................++
e is 65537 (0x10001)
$ openssl pkcs8 -in private.key -topk8 -nocrypt -out pkcs8.key
$ openssl pkcs8 -nocrypt -in pkcs8.key -inform PEM -out pkcs8.der.key -outform DER
$ file *.key
pkcs8.der.key: data
pkcs8.key:     ASCII text
private.key:   PEM RSA private key

As you may notice, almost all the cryptographic or PKCS files can be converted to DER format although they are not described in this post like the CRLs. To learn more about how you can convert a specific file, just run “openssl [command] --help" and check the options available.

Convert different cryptography files to PEM format

Normally, openssl generates files with PEM format, but there could be files in DER format that you may need to convert. By using the same option “-outform” from openssl you will be able to convert to PEM format.

If the Certificate Authority (CA) does not accept CSR in PEM format then you can convert it to DER format. To describe how you can do it, in the following code block first a CSR is created from a private key with a DER format and, afterwards, another openssl execution is done to convert the CSR to PEM format. Again, to verify the output as the previous section, the file command is run.

$ openssl req -newkey rsa:4096 -keyout private.key -out req.csr -nodes -subj '/CN=fse,/OU=test' -outform DER
Generating a 4096 bit RSA private key
.......................++
................................................................................................................................++
writing new private key to 'private.key'
-----
$ file req.csr
req.csr: data
$ openssl req -in req.csr -inform DER -out req.pem.csr -outform PEM
$ file req.pem.csr
req.pem.csr: PEM certificate request

Let’s do the same conversion with a public key. First, a private key is generated, next, a public key is derived from the private key but with DER format, then, openssl is run again to finally convert public key from DER format to PEM:

$ openssl genrsa -out private.key 4096
Generating RSA private key, 4096 bit long modulus
............................................................................++
......................................................................................................................................++
e is 65537 (0x10001)
$ openssl rsa -in private.key -pubout -out public.key -outform DER
writing RSA key
$ file public.key
public.key: data
$ openssl rsa -pubin -in public.key -inform DER -out public.pem.key -outform PEM
writing RSA key
$ file public.pem.key
public.pem.key: ASCII text
$ head -n 5 public.pem.key 
-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAybmBsRBfKcYAratN6QOq
MrUAUCK+XQUNzMENPkbgXdpxj0TcMC4W798Vin/IGQV7kvmkx0651ImXlblDQsMo
+Aq3xhUN8TF6ndGpSRSJ9Mjk9S5WOkGJ4ORyaA5QR7EgeiS5xu7P1BbONn1tLOwA
sg4jRh0OyVG6HqIHzfGf3rXzdrqPNUXCflJPaZmBIDvZW5P/vIbhACFlg6WCWpkZ

In this last conversion use case, a PCKS12 or p12 file will be converted from binary format to PEM format. So, for this purpose, a self-signed certificate is generated then, with both private key and the certificate a password-less p12 (Only for testing purposes) is created and, finally, the p12 is converted to PEM format without a password again:

$ openssl req -x509 -newkey rsa:4096 -keyout private.key -out cert.crt -nodes -sha256 -subj '/CN=fse'
Generating a 4096 bit RSA private key
..................................................................................................++
.........................................................................................++
writing new private key to 'private.key'
-----
$ openssl pkcs12 -inkey private.key -in cert.crt -export -out cert.p12 -nodes -passout pass:
$ file cert.p12
cert.p12: data
$ openssl pkcs12 -in cert.p12 -out cert.pem.p12 -nodes -passin pass:
MAC verified OK
$ file cert.pem.p12
cert.pem.p12: ASCII text
$ head cert.pem.p12 
Bag Attributes
    localKeyID: 20 DF 69 C2 8F E9 06 39 DE 94 0E A8 76 C8 17 27 C0 E1 6E 35 
subject=/CN=fse
issuer=/CN=fse
-----BEGIN CERTIFICATE-----
MIIE7zCCAtegAwIBAgIJAIXNSNh9mTMAMA0GCSqGSIb3DQEBCwUAMA4xDDAKBgNV
BAMMA2ZzZTAeFw0yMjA2MDYxODUwMjhaFw0yMjA3MDYxODUwMjhaMA4xDDAKBgNV
BAMMA2ZzZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANWy+8Bo1pMJ
6Rs0a/JP0ksdd0hYa6ggT7Ze8TPDVlcGW0utdM+g4ZX3uobypBLQXojkVnqvepx1
Zpa0NLO027sxuaW+ps9K4FQH6HLWi2jNzu+p/QlcZVuopVm9SpbN9XBFVwwqKfDt