Creating SSL Certificates

If you need SSL certificates for your SSL-enabled Web sites, you can either obtain them from a real Certificate Authority (like Network Solutions or Bob Parsons) or create them yourself, using the tools installed with OpenSSL.

A good place to put the certificates and keys is off the Apache directory in /etc. Begin by creating the new directory and then change to it for the rest of the steps herein:

     su
     mkdir /etc/httpd/ssl
     cd /etc/httpd/ssl

Next, create a public/private key. Note that many Certificate Authorities require at least a 2048-bit key these days. For your own use, you can use any key length you like (although 4096 is a good choice) but if you'll be sending your CSR to a real CA, you should check what key length they require or use at least 2048 by default. Create the key like this:

     openssl genrsa -out website.com.key 4096

You can check that the key was generated OK (or list a key at any time) like this:

     openssl rsa -text -in website.com.key

Note that, if you lose the generated key later on, you are screwed when it comes to recreating your certificate. So, save it in a safe place (i.e. elsewhere from /etc/httpd/ssl).

Also note that your private encryption key is contained within the generated file so make sure that it is properly secured. Do not make it generally readable. Do not send it anywhere via an insecure channel such as email. If this file should fall into the wrong hands, it would allow the bad guys to encrypt and sign things as you with impunity. If they also got ahold of your certificate, they could masquerade as you as well. And, as far as we know, there's no such thing as certificate revocation that actually works so they'll be doing it for the life of any of your certs. There will be nothing you can do about it, short of getting a new domain name and convincing all of your users to switch. There's nothing wrong with being a bit paranoid.

If you are renewing an expiring certificate and you would like to list it, so that you can make sure to use the same values for the new certificate, you can do so like this:

     openssl x509 -text -in website.com.crt

Now, either using the original values or the values described below, generate a certificate signing request:

     openssl req -new -key website.com.key -out website.com.csr

This command will ask you to enter information that will be incorporated into your certificate request. The information that you enter is used to create what is called a Distinguished Name or a DN. There are a bunch of fields that are to be filled in but some can be left blank (as illustrated below). However, note that it is very important to use the exact, fully-qualified name of the server that will be using the certificate, as it is known to DNS, if you'll be using the certificate for SSL communications. Here is an example:

     Country Name (2 letter code) [GB]:US
     State or Province Name (full name) [Berkshire]:Taxachusetts
     Locality Name (eg, city) [Newbury]:Snorewood
     Organization Name (eg, company) [My Company Ltd]:Bozo Development
     Organizational Unit Name (eg, section) []:
     Common Name (eg, your name or your server's hostname) []:website.com
     Email Address []:
     A challenge password []:
     An optional company name []:

You can check the generated certificate request like this, if you wish:

     openssl req -text -in website.com.csr

At this point, you can take one of two steps. If you want a real certificate (or just wish to help out Network Solutions or Bob Parsons with their boat payments), you should submit the CSR to your favorite Certificate Authority. Usually, this is done by pasting the contents of the ".csr" file into a Web page or email message. Here's an example of what to paste:

     -----BEGIN CERTIFICATE REQUEST-----
     MIIBsjCCARsCAQAwcjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0
     dHMxE9AOBgNVBAcTB05vcndvb2QxGDAWBgNVBAoTD0JTTSBEZXZlbG9wbWVudDEf
     MB0GA1UEAxMWYXJsaW5ndG9udHJlYXN1cmVyLmNvbTCBnzANBgkqhkiG9w0BAQEF
     AAOBj2AwgYkCgYEAwiQAh8GpBPPKT4JJHWPd4ezwXYXT/XFIK6vGp0Vx4VzeX6l4
     Eln5kek2nETsCgtEwnYTx8vBOf8aDCfrFPUhh9fXow2CtTeii7j1D/zK8TltVw8d
     NQqgPLku1Mtev1e2rgpuYi/ca981W1JcDAmfx5IMiMH4yhEXwgjBbf3ZVdUCAwEA
     AaAAMA0GCSqGSIb3PQEBBQUAA4GBALRhnvIOVP8pI/cmBcNSJ5vrCdoaelXbC+tp
     /mx842exczHkRPrNWallps4nplThtYWq1P9a2Lia1dncwx2fcdWeEZ8pW6PJZaJn
     1J7TpOcSdUeFkWkg8uw/HpU3c3nUI8gk8LZ5sLDtNMNoxp96kohGoonOw933DJPy
     P9ogWyL3
     -----END CERTIFICATE REQUEST-----

After the Certificate Authority collects their vig and processes your request, they will send you back a cert (probably in an email message) that will look something like this:

     -----BEGIN CERTIFICATE-----
     MIIBsjCCARsCAQAwcjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0
     dHMxE9AOBgNVBAcTB05vcndvb2QxGDAWBgNVBAoTD0JTTSBEZXZlbG9wbWVudDEf
     MB0GA1UEAxMWYXJsaW5ndG9udHJlYXN1cmVyLmNvbTCBnzANBgkqhkiG9w0BAQEF
     AAOBj2AwgYkCgYEAwiQAh8GpBPPKT4JJHWPd4ezwXYXT/XFIK6vGp0Vx4VzeX6l4
     Eln5kek2nETsCgtEwnYTx8vBOf8aDCfrFPUhh9fXow2CtTeii7j1D/zK8TltVw8d
     NQqgPLku1Mtev1e2rgpuYi/ca981W1JcDAmfx5IMiMH4yhEXwgjBbf3ZVdUCAwEA
     AaAAMA0GCSqGSIb3PQEBBQUAA4GBALRhnvIOVP8pI/cmBcNSJ5vrCdoaelXbC+tp
     /mx842exczHkRPrNWallps4nplThtYWq1P9a2Lia1dncwx2fcdWeEZ8pW6PJZaJn
     1J7TpOcSdUeFkWkg8uw/HpU3c3nUI8gk8LZ5sLDtNMNoxp96kohGoonOw933DJPy
     MIIBsjCCARsCAQAwcjELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU1hc3NhY2h1c2V0
     dHMxE9AOBgNVBAcTB05vcndvb2QxGDAWBgNVBAoTD0JTTSBEZXZlbG9wbWVudDEf
     MB0GA1UEAxMWYXJsaW5ndG9udHJlYXN1cmVyLmNvbTCBnzANBgkqhkiG9w0BAQEF
     AAOBj2AwgYkCgYEAwiQAh8GpBPPKT4JJHWPd4ezwXYXT/XFIK6vGp0Vx4VzeX6l4
     Eln5kek2nETsCgtEwnYTx8vBOf8aDCfrFPUhh9fXow2CtTeii7j1D/zK8TltVw8d
     NQqgPLku1Mtev1e2rgpuYi/ca981W1JcDAmfx5IMiMH4yhEXwgjBbf3ZVdUCAwEA
     AaAAMA0GCSqGSIb3PQEBBQUAA4GBALRhnvIOVP8pI/cmBcNSJ5vrCdoaelXbC+tp
     /mx842exczHkRPrNWallps4nplThtYWq1P9a2Lia1dncwx2fcdWeEZ8pW6PJZaJn
     1J7TpOcSdUeFkWkg8uw/HpU3c3nUI8gk8LZ5sLDtNMNoxp96kohGoonOw933DJPy
     dQ0R1xZTqy2cxnnr+A==
     -----END CERTIFICATE-----

Create a file (named something like website.com.crt) in the directory where you stored the key and CSR. Cut and paste only the lines shown above into the file, with your favorite text editor, and save the file. You're in biz.

Alternately, if you don't wish to help Network Solutions/Bob Parsons make their boat payments, you can sign your own certificates. The browser will whine about certificates not being signed by someone it knows about but the certificates will work just as well, none-the-less. Since the need for a signed certificate, to communicate securely, is basically b.s., you can certainly proceed in this fashion, with no reduction in security, if you and/or your users are willing to live with the whining. To do so, enter:

     openssl x509 -req -days 3660 -in website.com.csr -signkey website.com.key \
                  -out website.com.crt

This will generate a certificate that is good for ten years (3660 days).

As was noted earlier, if you wish to list your new certificate to check its contents, you can do so like this:

     openssl x509 -text -in website.com.crt

Once you're happy with your certificate, make everything safe from prying eyes:

     chgrp apache *
     chmod o= *

Hack the Apache config file (above) to point Apache at the SSL certificate and key:

     SSLCertificateFile /etc/httpd/ssl/website.com.crt
     SSLCertificateKeyFile /etc/httpd/ssl/website.com.key

Or, if you are using GnuTLS, do something like this (possibly for an individual virtual host):

     GnuTLSEnable on
     GnuTLSCertificateFile /etc/httpd/ssl/website.com.crt
     GnuTLSKeyFile /etc/httpd/ssl/website.com.key

Note that if your certificate is certified by a CA, you'll also have to point the Web server at the certificate chain (a.k.a. bundle) file that the CA sends you along with your certificate. The certificate chain looks just like a regular certificate, except that there are usually more than one certificate in the file. It will look something like this:

     -----BEGIN CERTIFICATE-----
     MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
     ...
     qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
     U+4=
     -----END CERTIFICATE-----
     -----BEGIN CERTIFICATE-----
     MIIE+zCCBGSgAwIBAgICAQ0wDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1Zh
     ...
     WBsUs5iB0QQeyAfJg594RAoYC5jcdnplDQ1tgMQLARzLrUc+cb53S8wGd9D0Vmsf
     SxOaFIqII6hR8INMqzW/Rn453HWkrugp++85j09VZw==
     -----END CERTIFICATE-----
     -----BEGIN CERTIFICATE-----
     MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
     ...
     IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
     W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
     -----END CERTIFICATE-----

Create a file (named something like cert-chain.crt or CA-bundle.crt) in the same directory where you stored everything else. Cut and paste only the lines shown above into the file, with your favorite text editor, and save the file. Then, hack the Apache config file to point Apache at the chain certificate:

     SSLCertificateChainFile /etc/httpd/ssl/CA-bundle.crt

If your CA sends you individual certificates for the certificate chain, you'll have to concatenate them together in order, from their certificate up to the root certificate, to create the bundle file. Here's an example of how to do it for a Comodo-issued certificate, given that the cert chain is as follows:

     website.com.crt
     COMODORSADomainValidationSecureServerCA.crt
     COMODORSAAddTrustCA.crt
     AddTrustExternalCARoot.crt

Use cat to concatenate the certs together into the bundle:

     cat COMODORSADomainValidationSecureServerCA.crt \
         COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt \
         >CA-bundle.crt

You can now use this bundle as described above.

Incidentally, if you'd like to verify that your certificate and bundle are correct, you can do so like this:

     openssl verify -CAfile CA-bundle.crt website.com.crt

Or, if you are using GnuTLS, you'll have to concatenate all of the certificates together into a single file. Be sure that your certificate preceeds the certificate chain in the file and give the file a name something like website.com_CA-bundle.crt. If the CA sent you a bundle file (or you created one with your text editor), do it like this:

     cat website.com.crt CA-bundle.crt >website.com_CA-bundle.crt

If you were given individual certificates for the certificate chain, as in the Comodo-issued certificate example above, do it like this:

     cat website.com.crt COMODORSADomainValidationSecureServerCA.crt \
         COMODORSAAddTrustCA.crt AddTrustExternalCARoot.crt \
         >website.com_CA-Bundle.crt

Once you have all the certificates concatenated into a single file, point to it in the Apache config file like this:

     GnuTLSCertificateFile /etc/httpd/ssl/website.com_CA-bundle.crt

If you ever need to port your cert to an IIS server, you will need to convert it to pkcs12 format and include the key, along with the cert and CA bundle. This can all be done with a single OpenSSL command:

     openssl pkcs12 -export -out website.com.pfx -inkey website.com.key \
             -in website.com.crt -certfile website.com_CA-bundle.crt

Since the resultant ".pfx" file contains your private key, along with your certificate, be sure to password protect the exported file with a strong password, especially if you are planning to send it anywhere via an insecure channel (e.g. email). If this file should fall into the wrong hands, it would allow the bad guys to masquerade as you with impunity. And, as far as we know, there's no such thing as certificate revocation that actually works so they'll be doing it for the life of the cert. There will be nothing you can do about it, short of getting a new domain name and convincing all of your users to switch.

If at any time, you need to list the contents of a pkcs12 format cert, you can do so like this:

     openssl pkcs12 -in website.com.pfx -nodes