Header Image - Learn Linux Online

Tag Archives

One Article

OpenSSL Generate: Certificates, CSRs, and Self-Signed CA Certificates

If you’re a computer novice, start reading this at the top. If you know what you’re doing (even somewhat).

Introduction (Crash Course for Beginners)

SSL Certificates are all about trust. It’s how a website tells a user: “Hey, I’m trust worthy because other people trust me, so you should too.” The primary tool of that trust? OpenSSL. Depending on your needs, you might use OpenSSL to:

  1. Generate a self signed certificate
  2. Generage a CSR (Certificate Signing Request)
  3. Become your own CA (Certificate Authority), and if you do that:
  4. Sign CSRs that have been created by others.

This tutorial is going to teach you how to do each one of these tasks, but first, let’s discuss the public key infrastructure (PKI) and the  various degrees of trust it has. The PKI was established as a way to tell a complete stranger that another complete stranger is a good guy or a bad guy. When a webmaster decides they need a “secure” website (an httpswebsite), they seek out a certificate authority to give them a certificate. (“Give” is not really the appropriate word, “sell” might be better!). The webmaster is essentially paying the CA to vouch for them.

In order for the Certificate Authority (CA) to vouch for a webmaster and his site, they need (at least) a minimum amount of information about that webmaster and his site. This very basic information is:

  • Your Country
  • Your State / Province
  • Your Locality (City, Town, Village, etc…)
  • Your Organization Name
  • The Organization Unit Name (If you have one… could be “Sales” or “Corporate” or “IT DIvision”)
  • The common name (this is the full URL of your website)
  • Your email address.

This information, plus confirmation that you have control of that domain (via email or uploading a special file to the root of your website) is usually enough to get you a basic SSL certificate. These basic certificates can range anywhere between $5 – $80 depending on the vendor.

There are more expensive certificates out there, which go up in price from $200 – $10,000+. These are known as “EV” or “Extended Validation” certificates. In order to qualify for one of these certificates, you have to submit much more information about you and your company (as well as the basics above). EV Certificates give you that pretty green bar at the top of our browser. SSL certificate vendors sell this as a way to get the utmost trust from consumers, but the reality is that most consumers don’t know the difference. So, while it may underwhelm you to see that Bank of America is using an expensive, fancy EV certificate:

It may be very interesting to note that Amazon.com does not use an EV Certificate:

So, whether or not you choose to pony up the extra cash to get an EV certificate really boils down to answering two questions:

  1. Are my visitors / customers tech savvy enough to notice that I am using an EV certificate (and therefore trust me more)?
  2. Do I have the extra cash to buy an EV cert or will a standard certificate suffice?

In this tutorial, we are going to focus on standard SSL certificates and generating our own self-signed certs and self-signed Certificate Authority certificates because it’s completely free.

We’re not going worry about EV.

But, there is a VERY IMPORTANT distinction between purchasing an SSL cert from an established certificate authority versus generating your own (certificate or CA), and that’s called “the trusted root”.

Commercial Certificate Authorities like VeriSign, Digicert, GoDaddy, among others have their certificates in the “trusted root” of many operating systems. This means that when they sign your CSR and issue you a certificate where they vouch for you, the resulting certificate will be automatically accepted by FireFox, Chrome, Safari, and Internet Explorer without any further action. If you generate your own certificates, strangers that come to your site will get a certificate warning instead of a lock on their address bar.

There is a way around this problem if you become your own Certificate Authority and install certificates onall your computers (and the computers of all the users that will access your website or email system), but if you’re looking to allow strangers to be able to trust yoru site without installing software on their computers, servers, or mobile devices, you need to get a for-pay certificate from a commercial CA!

A Note on How Keys, Certificates and Cryptography Work

It’s important that you understand that modern cryptography works on the principle that two VERY large prime numbers form a key pair. These huge numbers are used because it is unfathomably difficult to factor the sum of two large prime numbers back into those two numbers. The public and private key are (essentailly) those two large numbers. If you have the private key, you can encrypt or decrypt information. If you have the public key you can only encrypt it. So, when you create a certificate, CSR, or get your key “signed” by a CA, you are essentially dealing with a pair of very large prime numbers and their sum. For more information, read Plain English: an RSA Encryption and Authentication Primer.

Common Certificate Generation Tasks in OpenSSL

Generating a CSR (Certificate Signing Request) with OpenSSL

The CSR (Certificate Signing Request) is a text file that we generate with OpenSSL, which contains both of the following items:

  1. The organization information (noted above as Country, Province, Locality, Organization, Unit, common name, and Email address)
  2. The public key that was generated as part of the key pair.

The information provided in #1 above must be cryptographically signed with the private key, or the CA will not be able to verify the information sent to them in the CSR. (When you sign information with a private key, you can forward that information along with a public key to a third party, and that third party can verify the signature using the public key – BUT they cannot duplicate the signature without the private key, which is always kepts secret, and never leaves your possesion).

Here’s the code to generate a private key (from which a public can will be derived) and a CSR that can be safely forwarded to a CA for signing:

openssl req -new -newkey rsa:2048 -nodes -keyout yourdomain.key -out yourdomain.csr

Here’s what’s going on with this command:

req tells OpenSSL that we are requesting something

-new makes it a new request for a…

-newkey, which takes the parameter: rsa:2048RSA is the type of key we are creating, and 2048 is the strength (length in bits, whcih is directly related to the complexity of th key).

-nodes is frequently confused as “nodes” when in reality it means “no DES” or, “do not produce a PKCS#12 compiant file. Most certificate authories cannot use this type of file; however, this is the type of file that IIS (Internet Information Services) on Windows Server systems uses to store their certificate files. Specifying -nodes means that the resulting file will not be encrypted, which is perfectly fine since you’re going to be transmitting a public key, which does not need protection as well as public information about yourself and your server.

-keyout tells OpenSSL to write the key to yourdomain.key. You can make this any output filename you want, but it makes the most sense to label it as yourdomain.key. Many people (myself included) use -yourdomain.tld.key, which is particularly useful if you own both the .net and .com of a particular domain name.

-out tells OpenSSL ‘write the certificate signing request to this file”. This is the file that you will transmit (in the clear) to the CA for signing.

Once you have completed this step, you’ll want to make sure that you keep your .key file under wraps. You don’t ever want to lose control of this file because then an evil actor (bad guys) could replicate your keys, decrypt your traffic, or even spoof your site’s online identity. The CSR, however, you can email to the CA for signing or use thier upload system to send it in to be signed.

Here’s what the execution of this command looks like:

You can see that the first thing it does is generate an RSA private key, then it writes that key to the specified output file, learnlinuxonline.com.key as I specified in the command on the first line. Next, you can see it asked me for information about myself, my site, and our location. Since learnlinuxonline.com is a free service of my company, High Powered Help, Inc., I entered in the company information. You should also notice that I left the challenge passwordblank. If you were to include a challenge password during the creation of these certificates, you would be required to enter the password into Apache every time you booted, restarted the web server or every time you restart or reload the Apache service. Ultimately, this inconvenience would cause you to end up stripping out the password anyway. So, don’t bother putting one in to begin with.

The resulting files that are generated are learnlinuxonline.com.key and learnlinuxonline.com.csr:

And, here’s what the contents of the CSR look like:

I’ll even show you what the private key looks like because this key was generated specifically for this tutorial, and discarded. So, try as you might, it isn’t going to help you spoof my site. But even still, I obfuscated a few lines anyway…

Generating a self-signed certificate with OpenSSL

self-signed certificate is nothing more than fulfilling a certificate signing request with a key you generated yourself. It’s a big like writing your own recommendation letter. Others will take it with a grain of salt. But, if you are dealing with a small number of users or just doing something in a testing environment, this can be an easy way to develop an application or website without having to go through the expense of buying a certificate from a certificate authority.

The self-signed certificate procedure is rather simple:

  1. Create a private key.
  2. Create a CSR for your server
  3. Sign the CSR with the private key

How to Create a Private Key for Self-Signed Certificates

As always, we’re going to execute an OpenSSL command:

<b>openssl genrsa -des3 -out server.key <b>2048</b>

Here’s how the command works:

  • genrsa tells OpenSSL to generate an RSA based private key.
  • des3 tells OpenSSL to use triple DES encryption
  • out tells OpenSSL where to write the resulting keys (into which file)
  • 2048 tells OpenSSL to use 2048-bit long modulus, which is the current standard (as of this writing).

The command execution looks like this:

You’ll notice that it asks for a pass phrase to protect the private key. You can make this a simple, easy to remember (and even weak) password for now because we are just going to remove it in later steps.

 Generate a CSR

Now that we have a key, you’ll need to generate a CSR as shown above (in great detail). Once you’ve done that, come back here, and proceed to the next step.

 Using OpenSSL to Self-Sign your CSR to create the Self-Signed Certificate

Now that we have a private key with which we can do the signing and a CSR that needs to be signed, we’re almost ready to generate the certificate. But, as noted above, we’re going to need to remove that pesky password that we added to the private key before we can get started. Why? Because if you retain the password, you’ll need to enter it every time you restart Apache or reboot the server. That can cause a lot of downtime. Without the password, Apache cannot read the certificate (since it was encrypted with 3DES using that password as the key).

To prevent this pandemonium, we’re just going to remove the password and rely on file system permissions and security to keep the key safe. So, first we’ll make a backup of the original key:?

cp server.key server.key.backup

Then we’ll remove the password with this command:?

openssl rsa -in server.key.backup -out server.key

This command tells OpenSSL to read -in the original key (that we’ve saved as a backup copy) and output a pure RSA key (with no encryption) to the -out file server.key.

Now that we have a private key without a password, we’re ready to sign the CSR with that key to create the self-signed certificate:

The OpenSSL command for this is:

openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

This command has the following paremeteres:

  • x509 is the certificate type, which has been standardized for the Public Key Infrastructure (PKI). This format is required for browsers to be able to interact with them properly.
  • -req tells open SSL we are dealing with a CSR (request).
  • -days tells OpenSSL we only want to vouch for this certificate for X number of days. In most cases, 365 days for a self-signed certificate is sufficient. (Later, when we start running our own CA, you’ll see that  value go up to 730 days – two years).
  • -in tells OpenSSL what file to use as the certificate signing request.
  • -signkey tells OpenSSL which private key to use for the signing
  • -out tells OpenSSL where to write the resulting certificate.

The whole process looks like this:

How to become your own CA (Certificate Authority)

Becoming your own CA (Certificate Authority) is nothing more than having a specific private key that you use to sign all CSRs. It is essentially the same process that we used above in the section about creating self signed certificates, but the difference is: instead of using a throw-away key, we re-use a single key AND we have to install that key on computers that we want to recognize and trust us.

But first, before we go through this effort, let’s discuss when and why we want to be our own CA:

  1. You are generating a number of self-signed certificates that a number of users will all need to know and trust. (And you’re looking to save some cash).
  2. You are running a VERY high security application where you want to maintain 100% control over the entire trust chain.
  3. You think it would be fun.

In any case, you’ll need to have the UTMOST security precautions surrounding your master CA private key. I highly recommend that you store it on an encrypted drive with very strict file permissions (600) so that ONLY your user can access and deal with the key. It should never be stored “in the cloud” and it should be backed up in multiple locations (also encrypted). If you choose to use a cloud backup service, the only one I would recommend would be Carbonite, but ONLY if you use their RSA encryption backup scheme.

Bascially, you have to treat this private key like the most improtant, confidential, and sensitive data possible because it is.

Setting Up your OpenSSL Config File and CA Directories

As a Certificate Authority, you need to setup basic information and configurations so that your entire system is consistent. We also need to have a nice place to store everything. So, let’s first create a directory to store everything in /root/ca. We have chosen the /root/ directory to hold this information because it should be the most guarded account on your system. So, first: become root using either the sudo or su command:

sudo su

Now, change directory to the root user’s home directory, and create a directory structure for the CA system:

cd ~/ mkdir ca cd ca mkdir private mkdir certs echo "101010" > serial echo -n > index.txt echo "101010" > crl_number

You should now be in /root/ca/, and have an additional sub-directories certs and private in that directory along with three files: serial, index.txt, and crl_number. The serial file holds the serial numbers that willbe assigned to certificates as they are issued. index.txt is the database that holds information about certificates. With this directory structure setup, we are ready to configure our openssl.cnf file for our CA.

Download our example-openssl.cnf, and customize it to your own settings. Be sure to fill in the blank areas, and rename the file to openssl.cnf from example-openssl.cnf.

Make sure you keep this in the same directory that your private key and other root-ca data will be kept!

Generating a CA Root Certificate with OpenSSL

First, we’ll need to generate our root-ca private key using this command:?

[openssl genrsa -des3 -out root-ca.key 4096/bash] Next, we'll need to create the root-ca certificate [bash]openssl req -new -x509 -days 3650 -key root-ca.key -out root-ca.crt -config openssl.cnf

Once these have been generated, we need to put them in the directories that are specified in the openssl.cnf file for the CA. If you used the defaults, that would be /root/ca/private.

Installing your CA certificate in the trusted certificates store

Installing the CA Certificate in Linux (Ubuntu / Debian)

  1.  Create a directory in /usr/loca/share/ca-certificates to hold your cert.
  2. Copy the cert to that directory
  3. Run update-ca-certificates.

For example, you can create the directory (as root):

mkdir /usr/local/share/ca-certificates/yourdomain.com

Now, copy the cert there, or download it from the web using wget.

cp ./mycert /usr/local/share/ca-certificates/yourdomain.com/

or

wget http://certs.yourdomain.com/yourcert.crt

Then, once that is there, run update-ca-certificates to automatically update the system to trust that new certificate.

When you do it correctly, you should see output similar to this:

Installing the CA Certificate in the Windows Trusted Root Store

In order for your CA Certificate to be put into the trusted root store of a Windows computer (or server), you must first convert it to p12 format. The command to perform this conversion is:

openssl pkcs12 -export -out server.p12 -inkey root-ca.key -in root-ca.crt

This will output a file, server.p12, which you can then transport to your windows server and install.

For a Windows Computers (Workstations or Servers, individually)

The certificate can be copied to the desktop, and then, just double click it:

Make sure you select the Local Machine, not Current User.

Next, browse to the location of the p12 file. Remember to keep this file secure because it contains the private key!

When prompted for the password for the private key, leave it blank since we did not set a password when we exported the key to p12 format.

When prompted, select Trusted Root Certification Authorities as the designated certificate store:

When prompted to select the certificate store, do not let it “automatically” select. This will place the certificate in the least invasive store possible. Usually a personal store. We want this to be trusted absolutely, so we’re going to purposefully place it in the Trusted Root Certification Authorities store:

Lastly, confirm the import:

To confirm that the certificate was installed properly, you can find it in the certificate manager in Windows. Check the Trusted Root Certificate Authorities store, and you should find your certificate there next to Godaddy, Equifax, DigiCert, and other famous CAs.

For a Windows Domain (Group Policy)

To roll out your trusted root certification network wide using group policy, see the Microsoft Knowledge-base Article Use Policy to Distribute Certificates.

 Installing the CA Certificate in the Trusted Root of Macs

This section will be written in the future. If you really want it, leave a comment below to ping me.

Signing CSRs with your CA Certificate

By the time you reach this section of this tutorial, you should know that a CSR is generated by a client / third party who wants you to vouch for them. In general, when you sign a certificate signing request you are saying: “I know this person / organization, and their resources are legit.” So, you wouldn’t want to sign CSRs without doing some sort of confirmation that they are who they say they are. Typically, this includes ensuring that they have control over the domain that the SSL certificate will be used (domain validation) or even going as far as doing a background check on them (Extended Validation style).

If you’re running your own CA because you have a need for a lot of certificates that your own users will all be using, then you can probably vouch for yourself!

Bottom line, when you receive a CSR from a third party, figure out who they are before you sign it. If you’re generating the CSR requests yourself, then there is no one to check up on.

To sign a CSR with your root-ca certificate, execute the following command:

openssl ca -config openssl.cnf -out client.crt -infiles client.req

This, of course, requires that you copy client.req into the /root/ca/ directory so that it can be accessed. Additionally, it requires that you are root as well.

In our example, we are going to generate a CSR as if we were a third party. (This is the same procedure described above, but shortened because we are using it as an example):

This example creates client.key in our /root/ca/ directory, but since we would normally never have this file when filling a CSR request, let’s delete it. Thus, at this point, we have essentially “copied” the CSR into the ca directory to fulfill the signing request as if it had come in via email. So, our directory currently looks similar to this:

Notice that the only “new” file here is client.csr.

Now we are ready to sign the CSR (assuming you’re ready to vouch for the requestor!). To sign the CSR:

openssl ca -config openssl.cnf -out client.crt -infiles client.csr

This process will require that you:

  1. Enter the password for the CA certificate.
  2. Verify the information for the cert is as you expected it
  3. Confirm the certification commit

The resulting file, client.crt, is the certificate the requester can use on the mail, web, or other servers.

Here’s What Else Just Happened:

When you executed the signing of the certificate, a few other things happened as well, which are part of the record keeping process.

  1. A copy of the signed certificate was stored in the certs/ directory as {serial}.pem.
  2. The serial number in the serial file was incremented by 1, and the original was saved as serial.old
  3. The database (index.txt) was managed to keep any relevant information.

Because these things happened, it is wise to keep backups of your CA directory.