Managing SSL Certificates #2

Verifying that SSL certificates match their date, domain and even their key file before making them live on a web-server will reduce site down-time. This article will explain how to do that.

We'll then finish up with the answer to a common problem: how to un-password protect an SSL certificate file so that your web server starts on boot without human intervention.


OpenSSL — command-line tests

In Managing SSL Certificates #1, we showed you how to use symbolic links to more efficiently manage SSL certificate updates. The second part of avoiding certificate issues is to test the certificate for date, domain and a matching key before you restart a live web server. This is especially important after updating a certificate.

You can use the 'openssl' command to check that a certificate matches the domain data that you think it should contain. Here's how:

openssl x509 -text -in /etc/httpd/conf.ssh.crt/www.example.com.crt.2010

The output should like this; note I've truncated it here to save space:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            62:10:03:8c:48:68:00:70:0e:f2:34:dd:16:ee:5c:3c
        Signature Algorithm: sha1WithRSAEncryption
        Issuer: C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com
        Validity
            Not Before: Aug 11 00:00:00 2010 GMT
            Not After : Sep 10 23:59:59 2011 GMT
        Subject: O=www.example.com, OU=Go to https://www.thawte.com/repository/index.html, OU=Thawte SSL123 certificate, OU=Domain Validated, CN=www.example.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                    00:b1:c5:fa:05:5a:8a:1a:66:e1:4e:eb:c5:4d:15:
                    59:57:4b:09:82:ab:76:57:9d:c0:1d:4d:df:d7:0a:
                    d1:88:97:ce:b4:af:50:e3:5d:67:f8:ba:de:84:2f:
                    51:ec:9c:14:d2:54:04:f3:b1:7a:1a:f2:47:8c:cc:
                    da:b5:ea:d6:1a:14:7b:b6:a7:22:f3:86:b7:e2:cd:
                    e3:04:52:b4:c1:91:a1:64:78:0e:20:e1:35:93:5c:
                    80:e3:26:5c:b3:31:43:3d:b2:05:44:f1:59:5d:06:
                    a2:8e:3b:77:68:3c:c4:7b:12:53:47:d7:ba:92:01:
                    e2:a2:58:e2:60:66:83:3d:8b
                Exponent: 65537 (0x10001)
...
[truncated]

Note the CN=www.example.com buried early in the output above, as well as the start and expiry dates.

It's important to run this test against the real file, NOT the symbolic link! That way, you know for sure which certificate file you are really testing.

Similarly, to check an RSA key, which should show you the same modulus string as you saw in the certificate file:

openssl rsa -text -in /etc/httpd/conf/ssh.key/www.example.com.key.2010

I've again truncated the output, but you should see something like this:

Private-Key: (1024 bit)
modulus:
    00:b1:c5:fa:05:5a:8a:1a:66:e1:4e:eb:c5:4d:15:
    59:57:4b:09:82:ab:76:57:9d:c0:1d:4d:df:d7:0a:
    d1:88:97:ce:b4:af:50:e3:5d:67:f8:ba:de:84:2f:
    51:ec:9c:14:d2:54:04:f3:b1:7a:1a:f2:47:8c:cc:
    da:b5:ea:d6:1a:14:7b:b6:a7:22:f3:86:f7:e2:cd:
    e3:05:52:b4:c1:91:a1:64:78:0e:20:e1:35:93:5c:
    80:e3:26:5c:b3:31:43:3d:b2:05:44:f1:59:5d:06:
    a2:8e:3b:77:68:3c:c4:7b:12:53:47:d7:ba:92:01:
    e2:a2:58:e2:60:66:83:3d:8b
publicExponent: 65537 (0x10001)
...
[truncated]
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCxxfoFWooaZuFO68VNFVlXSwmCq3ZXncAdTd/XCtGIl860r1Dj
XWf4ut6EL1HsnBTSVATzsXoa8keMzNq16tYaFHu2pyLzhvfizeMEUrTBkaFkeA4g
4TWTXIDjJlyzMUM9sgVE8VldBqKOO3doPMR7ElNH17qSAeKiWOJgZoM9iwIDAQAB
AoGAJOV0KNxLwYMMzDZ+8qq1qjp2tNola7XgA7T/+j/SkUkAq9ufLDFcvPD78e9o
T3VtlOG/TmzOfP1AAGccFZmx6csaQxil2u9HcOOw4yZzqn8LBFRSSd0Ygy0+VmGF
nrYTaD/8VFV8FZOo1nye3TyUk3pePsnXedQR9H5kd5nFfPECQQDhcKaiFk2ADoxq
Ub2yA7lBI0OQmnk0RjDLqEb612ENmsWrpkCl5OqRgJbuLe7qTeENACh2Ko8lxf2B
uP4eihrlAkEAyd8rN6jLHsTltOCbv2RDeTrf/CSas2cBMRhhwMULJ0T55kooSJYU
IfmJSTJAdMu+5EfYk2UbJarhb9FNiUK/rwJBAIKnZQt/XX8f72UW5peq7MzBgUDn
JeOT4mfFqQ1rkcXusy0d902t8/xLyC1V1adZZ1q/grOpSrkbnCZ4bl6Ir7kCQAUf
W5pi9xyFxIptdKZLpgaqfsqIJ0DMKVSUmM5qcZkCgBDe6tzEqigei+RGmSodjW9/
fzhmRWUUS/opZn1IK1MCQQDNvLkaan5CUa1o1kCX2dFZbxh5mkMIvN01aPuG038Q
83TECLq0jtEvuV3a+CN1YYaP+igUnRuzIPBLZ+zjxMP9
-----END RSA PRIVATE KEY-----

You can probably guess which part of that command you would change to check a DSA key.

The 'openssl' tool can also be used to check that the encrypted content of a key and certificate pair really do match — without the pain of having to compare those two modulus strings line by line.

Openssl's modulus test will do this for you and provide you with a short hash of the critical content. If the hash — or modulus — for the key file is identical to the hash for the certificate file, you know the certificate and key file belong to the same pair.

Issue these two commands to perform the test:

openssl rsa -noout -modulus -in /etc/httpd/conf/ssl.key/www.example.com.key.2009 | openssl md5
4cb1f8bfbb0a1467f99120886559f7f8

openssl x509 -noout -modulus -in /etc/httpd/conf/ssl.crt/www.example.com.crt.2009 | openssl md5
4cb1f8bfbb0a1467f99120886559f7f8

Note how the has results for both files' modulus s strings are identical.

Here's how those commands might look when run against real files for a domain "www.domain.com" — the key happens to come from an earlier attempt to create an SSL certificate for this domain:

openssl rsa -noout -modulus -in /etc/httpd/conf/ssl.key/www.domain.com.key.2009 | openssl md5
58cfc8c1e97228d9b9481cfc71a1a990

...

openssl x509 -noout -modulus -in /etc/httpd/conf/ssl.crt/www.domain.com.crt.2009 | openssl md5
4cb1f8bfbb0a1467f99120886559f7f8

Note how the modulus results do not match!

That's a sure sign that the web server will hiccup if you attempt to load those files.

Remember, it's not the names of the key file and certificate file that matter here. The test is checking the encrypted SSL content of each file and producing a check-number — a hash — from each file.

In summary, for clarity's sake:

If a key and certificate go together, the hashes will be identical. If they don't go together, the hashes will not match. If they don't match, your SSL site will break when you try to reload it with that key and certificate pair.

Removing a passphrase

People often accidentally password-protect their SSL private key when they first create it. They subsequently find that their web server will not start automatically on reboot. Instead, it waits for the slice owner to type in the password at the console.

Here's how you can remove a key's password:

1.  Identify the name and location of the SSL key file. For example:

     /etc/httpd/conf/ssh.key/www.domain.com.key.2009

2.  Run the following command:

openssl rsa -in /etc/httpd/conf/ssh.key/www.domain.com.key.2009 -out /etc/httpd/conf/ssh.key/www.domain.com.key.2009.no_password

3.  Now copy off /etc/httpd/conf/ssh.key/www.domain.com.key.2009 for roll-back reasons:

mv /etc/httpd/conf/ssh.key/www.domain.com.key.2009 /etc/httpd/conf/ssh.key/www.domain.com.key.2009.needs_password

4.  And replace it with the password-less key:

mv /etc/httpd/conf/ssh.key/www.domain.com.key.2009.no_password /etc/httpd/conf/ssh.key/www.domain.com.key.2009

If you are using the symbolic link trick explained above, you would be able to carry out steps 1-4 without altering the '/etc/httpd/conf/ssh.key/www.domain.com.key' link, and without having to edit the web-site configuration file.

Of course, the syntax varies for SSL .pem files because each contains both a key and a certificate. However, the certificate check technique is still valid and you simply apply it to the one .pem file.

Summary

This article has shown you how to inspect the contents of SSL certificates, and how to check whether a certificate matches a given key. We finished up with a helpful tip for anyone who accidentally password -protected their SSL certificate file.

With these tips, you should be able to prevent your SSL certificates from causing you web-site down-time.

Article Comments:

Aaron commented Thu Mar 11 04:44:42 UTC 2010:

These tutorials are great. But I see you're using a 1024 bit key for this example.

Godaddy is forcing us to renew our ssl with a 2048 bit key. Will nginx require any changes beyond a restart after I replace our old .crt and old 1024 bit key with a new 2048 bit key with it's new .crt?

Want to comment?


(not made public)

(optional)

(use plain text or Markdown syntax)