Generating SSL Certificates signed by a Private Root

Most programs that make use of cryptography just use the libraries that openssl provides. However, openssl also provides a scriptable interactive shell environment that can easily be used to create digital certificates.

Here we’ll discuss the steps needed to create a root certificate and use it to sign an x.509 server certificate we will use to provide an 802.1x secure wireless network using WPA2 and EAP-TTLS.

These certificates would also be suitable for securing http connections to Apache or IIS web servers, however, private root certificates need to be distributed and installed on client devices before the server certificates they’ve issued can be used. This problem of root key distribution seriously limits the scalability of a security solution based on privately signed certificates.

Happily, EAP-TTLS does not require client certificates, Moreover, the certificates we generate only need to be installed on our RADIUS server, and they will only be used when our wireless devices connect to our APs. In a very limited deployment like this, private certificates are perfect because they also have a very low cost.

The Root Certificate

In a nutshell, creating a root certificate consists of three steps:

1. Generate a private key using something similar to the following command:

openssl genrsa -aes256 -out root-cert.key -passout stdin 2048

Once you issue this command, the program waits for you to key in a passphrase, but we could have just as easily specified a file as the source. This generates a 2048 bit private key, outputs it in PEM format to a file called root-cert.key, and encrypts it using 128-bit AES.

2. Generate a certificate signing request (CSR) including the private key:

openssl req -new -key root-cert.key -out root-cert.csr -text

When you run this command, you will first need to provide the passphrase you used to generate the private key. You will then be prompted for information to complete the various fields of the request:

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter ‘.’, the field will be left blank.
—–
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Ohio
Locality Name (eg, city) []:Cincinnati
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Company
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:ca.somecompany.com
Email Address []:hostmaster@somecompany.com

Please enter the following ‘extra’ attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

As noted, the state field should be the full name — Ohio and not OH. Using the postal abbreviation will make the resulting certificate unusable (at least in IIS and IE). Also, the common name is the DNS name of the server the certificate will be issued to. In this case we are generating a private root certificate, so we can just make up a name for it. The data in the remaining fields can be entered in whatever format you choose, or skipped completely.

3. Finally, sign the CSR and issue the certificate.

Since we will be issuing this certificate for a specific period of time, we should verify and correct the date and time before proceeding. Also, we need an extra argument to make this a root certificate, but otherwise the command would be the same for an ordinary server certificate.

openssl x509 -req -extensions root_ext -in root-cert.csr -signkey root-cert.key -out root-cert.crt -days 365

This example outputs a certificate called root-cert.crt in PEM format which is valid for 365 days. However, we’d probably want to use a longer duration for the root so it doesn’t have to be regenerated every year.

Finally, we need an additional file from which to read the serial number of the certificates this CA issues. Create a text file in your working directory called root.srl that contains an even number of bytes — something like the following using any hex string you like:

echo “0A01” >> root.srl

The Server Certificate

The steps here are almost the same as the above, so we’ll repeat them here quickly, noting only the differences.

Generate the server private key.

openssl genrsa -aes256 -out server.key -passout stdin 2048

Generate the CSR making sure to use the DNS name of the server that will have the certificate as the common name.

openssl req -new -key server.key -out server.csr -text

Sign the server CSR with the root certificate, issuing the server certificate.

openssl x509 -req -in server.csr -CA root-cert.crt -CAkey root-cert.key -out server.crt -days 365 -CAserial root.srl

Finishing Up

All that’s left is installing the root and server certificate on the server. Since this process differs depending on the OS and application we’ll cover that in separate documents.

Windows instructions can be found here.

Apache instructions are here.

Freeradius instructions are here.

Leave a Reply