Tech Blog.

Thoughts, stories, ideas.

Creating OpenSSL x509 certificates

29. June 2017

There are (still) various servers on the internet that have just an insufficient SSL/TLS configuration or none at all. It is not just web servers (like nginx or Apache) but also XMPP/Jabber servers and mail servers, for example. As the basis of each SSL/TLS configuration, we need keys and certificates and sometimes Diffie-Hellman parameters. This article is intended to summarise and briefly explain the most important OpenSSL commands.

Creating keys and certificates

In order to create keys and certificates manually, here are some different useful commands and their explanations.


Certificates and keys can be saved in a few different formats. In the following, we always use the PEM format, which most tools support the best. However, the files are larger than, for example, the DER format, since PEM consists of ASCII characters and DER is binary. Common extensions for PEM certificates are .pem or .crt. Certificates in DER format should end in .der.

PEM format is easy to recognise, because the contents of the files start with -----BEGIN CERTIFICATE----- and end with -----END CERTIFICATE-----. A good overview of the formats and how to convert them into other formats can be find at

The following is a list of the most common formats:

  • PEM: Extension .pem, .crt, .cer
  • DER: Extension .der
  • PKCS#7: Extension .p7b, .p7c
  • PKCS#12: Extension .p12
  • PFX: Extension .pfx

Create Certificate Signing Request

Certificate Signing Requests (CSR) are requests for certificates. They then have to be signed either by a Certificate Authority (CA) or self-signed. In order to create a CSR, it is first necessary to create a private key. Normally, every time a certificate is requested, a new Certificate Signing Request has be created.

The first step is to create a 4096 Bit RSA key. This can be considered secure by current standards. The second step is to create the CSR which is signed with SHA256 (many default values are still SHA1, so it’s absolutely necessary to indicate SHA256 explicitly). More information on creating RSA keys is available on the man page of genrsa, and more information on creating Certificate Signing Requests is available in the man page of req.

$ openssl genrsa -out 4096
$ openssl req -new -sha256 -key -out

This can also be done in one step. A CSR is created directly and OpenSSL is directed to create the corresponding private key.

$ openssl req -new -sha256 -nodes -newkey rsa:4096 -keyout -out

Create self-signed certificate

Self-signed certificates can be used in order to test SSL configurations quickly or on servers on which it has never been verified if a certificate has been correctly signed by a Certificate Authority or not. They can be created using the following command. It creates a private key, from which it generates a Certificate Signing Request and signs it with the private key. This results in a certificate which is stored in

$ openssl req -x509 -sha256 -nodes -newkey rsa:4096 -keyout -days 730 -out

Creating your own CA and using it to sign the certificates

Normal certificates should not have the authorisation to sign other certificates. This should be done using special certificates known as Certificate Authorities (CA).

If the number of clients is manageable or in other special cases, you can create your own Certificate Authority (CA). This is necessary for many Virtual Private Networks (VPN), for example, because the server certificate and all the client certificates have to be signed.

First, we create a file (e.g. file name x509.ext), in which the x509 extensions are defined. There are two sections – the one for the CA and the one for server certificates.

[ ca ]
# X509 extensions for a ca
keyUsage                = critical, cRLSign, keyCertSign
basicConstraints        = CA:TRUE, pathlen:0
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid:always,issuer:always

[ server ]
# X509 extensions for a server
keyUsage                = critical,digitalSignature,keyEncipherment
extendedKeyUsage        = serverAuth,clientAuth
basicConstraints        = critical,CA:FALSE
subjectKeyIdentifier    = hash
authorityKeyIdentifier  = keyid,issuer:always

After that, we create the CA and the server certificates.

In the first step, a new private key and a certificate are created, which then serve as the Certificate Authority. In this example, the certificate of the Certificate Authority has a validity period of 3 years. This certificate may only be used to sign other certificates (this is defined in the extension file in the section ca).

In the second step, the server certificate is created and signed by the CA. The server certificate is given a validity period of 2 years. In addition, a CA serial number file is created if one doesn’t already exist. The CA needs this file in order to know the current serial number. The server certificate is limited with regard to signing, in that it can only act as a server or client and cannot sign any other certificates. Further information can be found in the man page of x509 and x509v3_config.

$ openssl req -new -sha256 -nodes -newkey rsa:4096 -keyout CA.key -out CA.csr
$ openssl x509 -req -sha256 -extfile x509.ext -extensions ca -in CA.csr -signkey CA.key -days 1095 -out CA.pem
$ openssl req -new -sha256 -nodes -newkey rsa:4096 -keyout -out
$ openssl x509 -req -sha256 -CA CA.pem -CAkey CA.key -days 730 -CAcreateserial -CAserial -extfile x509.ext -extensions server -in -out

Viewing certificate and Certificate Signing Requests

The contents of certificates and Certificate Signing Requests are best viewed with OpenSSL. In addition to displaying the entire contents (-text option) it is possible to just display some parts. For example, the date of creation and expiration can be displayed using -dates. The corresponding list can be found in the man page (man 1 x509) under the entry Display options.

  • Certificate
    $ openssl x509 -in -noout -text
  • Certificate Signing Request
    $ openssl req -in -noout -text

Creating Diffie-Hellman parameters

Diffie-Hellman parameters are required for Forward Secrecy. The following command creates Diffie-Hellman parameters with 4096 Bits. You don’t have to create such large parameters. 2048 should also be sufficient. Creating the parameters can take an extremely long time, depending on the system. It may be worthwhile to create them on a hardware system (since there is more entropy) and then transfer them to a virtual system.

$ openssl dhparam -out dh4096.pem 4096


Certificates can be converted to other formats with OpenSSL. Sometimes, an intermediate step is required. The most common conversions, from DER to PEM and vice-versa, can be done using the following commands:

$ openssl x509 -in cert.pem -outform der -out cert.der


$ openssl x509 -in cert.der -inform der -outform pem -out cert.pem

The PKCS#12 and PFX formats can be converted with the following commands.

PFX (private key and certificate) to PEM (private key and certificate):

$ openssl pkcs12 -in keyStore.pfx -out keyStore.pem -nodes

PEM (private key and certificate) to PFX (private key and certificate):

$ openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt

Other commands on conversion can be found at the site already mentioned above (