Creating a signed SSL certificate

You disabled JavaScript. Please enable it for syntax-highlighting, or don't complain about unlegible code snippets =) This page doesn't contain any tracking/analytics/ad code.

Signing SSL certificates

For serving a website over https, you'll need a signed SSL certificate. There are two ways to get one:

  1. Create and sign one yourself. This will lead to the visitors of your website seeing the This Connection is Untrusted screen and needing to add an exception before being allowed in. Sadly, by now, most users simply click through that warning.
  2. Ask a Certificate Authority (CA) to sign yours. This will lead to visitors of your website being let in right away and seeing the little padlock in the browser - giving them a sense of trust. There's a list of "root" CAs trusted by OSes; here's the Windows 8+ list, the OSX Yosemite list, and on Linux, Firefox has a builtin list which Chrom{e,ium} also uses.

Let's start with self-signing so we can see how the whole process goes and already try it out on a server and then see how the "official" way goes.


At its core, this is a simple three-step process with many options:

1. Create a Private Key

This is very much the same as with ssh-keygen:

><((("> openssl genrsa -out lbeyer.key 4096

You need to keep this file safe, but accessible by any executable which should make use of the certificate, e.g. the webserver, so be careful about the permissions of this file.

Additionally, you may password-protect it by passing -aes128, -camellia128 or any other supported cipher as an additional flag. (Before the key length.) If you do so, you'll be asked to enter that password whenever you use the key, this includes your webserver starting.

We chose to use a 4096-bit key, which is currently the recommended setting. You can verify this really happened via openssl rsa -in lbeyer.key -text -noout | grep bit.

You could now extract a public key out of it and use them as keypairs, but we don't really need that for signing certificates, it's purely out of curiosity:

><((("> ssh-keygen -y -f lbeyer.key >

2. Create a Certificate Signing Request (CSR)

><((("> openssl req -new -key lbeyer.key -out lbeyer.csr -sha512

This will ask you all kinds of informations which will be included in the final certificate, i.e. publicly visible to the visitors of your site. Most of them are self-explanatory, but note that A challenge password is not the same as the private key's password. For now, you don't need it.

This generates the lbeyer.csr file which contains all the information you entered as well as a public key to go along with your private key.

The -sha512 is the digest you request to be used for the signature. You should not use anything older than SHA-256 here.

Again, you can verifydouble-check that everything has been correctly recorded in the request by running:

><((("> openssl req -in lbeyer.csr -noout -text

3. Create a Certificate Signed by Your Private Key and the CSR

><((("> openssl x509 -req -days 365 -in lbeyer.csr -signkey lbeyer.key -out lbeyer.crt

There's nothing special to talk about here, really. The -days 365 chooses for how long the certificate lbeyer.crt will be valid. After that amount of time, we'll have to check back. I'll update this snippet with instructions on what to do when I'll get there.

Now you can check for the validity

><((("> openssl verify lbeyer.crt

and the contents of the certificate with the usual command:

><((("> openssl x509 -in lbeyer.crt -noout -text

4. Create Stronger Diffie-Hellman Parameters

This is optional, but highly recommended, as OpenSSL defaults to only 1024 bits for creating a DH key, which would render our use of more bits (almost) useless. For a more in-depth explanation, see the "Forward Secrecy & Diffie Hellman Ephemeral Parameters" section at raymii's page.

><((("> openssl dhparam -out dhparam.pem 4096

Then, you'll have to set this up in your server config along with your private key and the certificate.

Signed by a CA

This is basically still TODO

But Soon:

If it's not by a trusted root CA, but by an intermediary, need to configure the server to send both ours and the intermediary one to the client!

Have a nice day!