The OpenSSL beginner's guide to creating SSL certificates

tl;dr: The commands and flags of OpenSSL are everything but intuitive. Fortunately you only need a few to create SSL certificates, which will probably one of the most common scenarios for using OpenSSL.

When I started using OpenSSL, I was in precisely the situation he describes so well. It's so discouraging running these commands:

$ openssl --help
openssl:Error: '--help' is an invalid command.
$ man openssl
No manual entry for openssl

However, over time, I learned my way how to use OpenSSL. I am certainly not an expert on OpenSSL, but I know how to help myself and know the commands that are relevant for me and my everyday life. Therefore, I would like to share my experiences and explain the commands that I have learned to use, hoping that this will make it easier for someone else to get started.

Creating a private key

Usually the first thing you need to do is to create a private RSA key. For this, OpenSSL has the genrsa command. By default, it creates a 512 bit private key (which is pretty weak), and it prints it to the terminal. To change this you need to specify the -out flag and a filename, as well as the number of bits you want to use for the key.

The more bits you use, the stronger the key will be - but the longer any calculations will take, too. Currently you should either use 2048 bits, or if you want to be ready for the future, directly use 4096 bits:

$ openssl genrsa -out privateKey.pem 4096

This creates a new file in the current directory, privateKey.pem, whose contents look similar to this. As you can see from the file name, the private key is stored using the so-called PEM format, one of multiple possible formats that are typically used to store keys:

-----BEGIN RSA PRIVATE KEY-----
MIIJKgIBAAKCAgEA3J9zsribIEmDGv1nU51CgwY6PfQCW3KD/MEEW+uCk/3fzZ/H
5zTN6Ah/nbioxOEUd4k4/iUCp6ozmbs9T3ORFgEkC9CRMDVPolI4LVOjev+QC38j
PsMEapA+T64Bxm9xM1BnNJRDbkN/GqX8Ak0vido+3se78vnNAhG0P7pswMNW1rjR
[...]
ujFz7oUPeXnbFVgHQRDUD5EHKXY9arx+7P3Bpala4Xw2kJ8290AqXwiHsZ8LqNAY
cWa7jujAMYlYYN42e5vKX2ryA2kIbItb71Dwdys6EmlitpB72HBQ2RcRJmRJa4fk
t/7vtlhJBVVkCWiXujUugK0zLt147PxS6kEipoPh1zCwJ/n0ESVKT3Os1ycQSA==
-----END RSA PRIVATE KEY-----

Creating a Certificate Signing Request (CSR)

The most common reason for creating a private key is because you want to have an SSL certificate. It doesn't matter whether you want to create a self-signed certificate on your own, or if you are going to buy an official one - the initial steps are always the same.

So, next you need to create a so-called Certificate Signing Request (CSR), which is like the order for your certificate. For a CSR to work you need to specify information, such as what your name is, for which domain the certificate is intended, and so on…

For creating a CSR, OpenSSL has the req command. Since you want to create a new CSR, provide the -new flag. You also have to specify the private key using the -key flag, and (again) the -out flag so that the CSR is written to a file. OpenSSL then asks you a number of questions, so that it learns about the information that need to be put into the CSR:

$ openssl req -new -key privateKey.pem -out csr.pem

What's really important here is the so-called Common Name, which is the fully-qualified domain name (i.e., including sub-domains) that you want to use the certificate for, e.g. www.thenativeweb.io or localhost. Please note that you must be the owner of a domain to acquire an official certificate for it. For this reason you will not be able to get an official certificate for localhost, but you can still create one on your own.

When OpenSSL asks you about a challenge password, simply leave the field blank. The CSR then gets created, again in PEM format, and if you take a look inside the generated csr.pem file its contents are similar to this:

-----BEGIN CERTIFICATE REQUEST-----
MIIE6DCCAtACAQAwgaIxCzAJBgNVBAYTAkRFMRswGQYDVQQIDBJCYWRlbi1XdWVy
dHRlbWJlcmcxHjAcBgNVBAcMFVJpZWdlbCBhbSBLYWlzZXJzdHVobDEcMBoGA1UE
CgwTdGhlIG5hdGl2ZSB3ZWIgR21iSDESMBAGA1UEAwwJbG9jYWxob3N0MSQwIgYJ
[...]
pZDHCFOc+lTmrwmcQNNN8xCg3V3Tf8obxgdTJXADcV5ac16rres/twjpWjHyw3qX
HehmvCOdO/WNbcT866/Uw/7FzrZ+Lpv7rKQRd3LJ7KaIHwkcfczlr5zsXawnR0Zz
PTU9OorKDIVGL+Pv
-----END CERTIFICATE REQUEST-----

The CSR contains all the information you entered in an encoded form, but not your private key. Hence it is safe to hand over the CSR to a third party, but you should never do this with your private key! If your private key is ever disclosed or leaked, immediately consider it as compromised and replace it with a new one.

Getting an SSL certificate

Now there are two options of how to proceed. If you want to buy an official certificate that is trusted by common web browsers, send the CSR to a certificate authority (CA), pay, and wait for the certificate being returned. The certificate will probably be in PEM format again.

Depending on your infrastructure, you may need to convert the certificate to another format, but e.g. if you are using Node.js, PEM is perfectly fine. Now you don't longer need the CSR, so you can safely delete the csr.pem file.

If you want to create a self-signed certificate, you can use the x509 command of OpenSSL. You need to provide the CSR using the -in flag, and (again) the -out flag to specify the file name where the certificate should be written to. Additionally, you need to set the -req flag.

You also have to provide the private key using the -signkey flag, as this private key is now not only used as private counterpart to the certificate, but also to sign the certificate (hence the name self-signed certificate).

Finally, you need to provide the -days flag and specify the number of days the certificate should be considered valid. Typical values are 365, 730 and 1095, for certificates with a runtime of 1, 2, and 3 years:

$ openssl x509 -in csr.pem -out certificate.pem -req -signkey privateKey.pem -days 365

Once the certificate.pem file was created, you don't need the csr.pem file any more, so you can safely delete this file now. If you take a look at the contents of the certificate.pem file, it already looks familiar:

-----BEGIN CERTIFICATE-----
MIIFwjCCA6oCCQDS/1yqqOIbKzANBgkqhkiG9w0BAQUFADCBojELMAkGA1UEBhMC
REUxGzAZBgNVBAgMEkJhZGVuLVd1ZXJ0dGVtYmVyZzEeMBwGA1UEBwwVUmllZ2Vs
IGFtIEthaXNlcnN0dWhsMRwwGgYDVQQKDBN0aGUgbmF0aXZlIHdlYiBHbWJIMRIw
[...]
MVBQYgl9sPNrQhJTw1FF2RIEFEsdPyiOIrVU6cFegCHEARYVOrxVvhgbEoHk75EZ
rqcl5ZegKHVMnoy0Xz/qYTIyneU83Pmkz4fa/ZK++H5PfjJDgz6RjlwMTkzGIGVC
4vhPucnVwcRh4BjqI1OzLRDD4jDgaSjg06GJSYXV8OvOZt+DgSY=
-----END CERTIFICATE-----

Inspecting a certificate

From time to time you may want to figure out the details of a certificate, e.g. to lookup which domain a certificate was made for, or when it is about to expire. Luckily, OpenSSL can do this for you as well, again using the x509 command.

You need to provide the certificate to inspect using the -in flag. Since you want the certificate's details in text form, provide the -text flag, and - which comes as a surprise - you need to set the -noout flag to force OpenSSL not to write the output to a file, but print it to the terminal:

$ openssl x509 -in certificate.pem -text -noout

That's it. You now have a private key and a certificate, that you can use to run an HTTPS server. And that's the least you need to know when trying to use OpenSSL as a beginner, so that you don't give up frustrated.

Admittedly, the commands and flags are not really intuitive and easy to remember, but on the other hand you don't need them every single day. It's perfectly fine if you know where to look them up when you need them.

Twitter Facebook LinkedIn

Golo Roden

Founder, CTO, and managing partner

Since we want to deliver elegant yet simple solutions of high quality for complex problems, we care about details with love: things are done when they are done, and we give them the time they need to mature.