Saturday, June 7, 2008

Self-Signed Certificates: How to get Cross Browser Compatibility with Wildcard Domains


A self-signed SSL certificate is a convenient  way to encrypt data between your own web server and web requests you make to it over the wider Internet. If you own multiple domains or run multiple sub domains, say as virtual hosts in Apache then creating a certificate that won't cause errors on Firefox, Opera and Internet Explorer 5,6 and 7 is non trivial, there are a few tricks which are only tucked away on some remote message boards - so I have summarized them here.

Creating a self-signed certificate for a single domain name is simple and covered in multiple places with easy to follow guides such as at

Wildcard certificate guides are a little rarer, however the one that this tutorial is based upon is below

The above guide is essentially no more difficult than simply using * for the common name of your server when you come to generate the certificate, there are a number of problems with this simplistic approach when it comes to supporting multiple domains and subdomains on the same I.P addresses. As we must present the certificate BEFORE we can accept traffic there is no way for us to know which domain has been requested - thus all domains must be supplied with the same certificate.

The Problem

  1. I.E 5 and Firefox (tested on 2.*) don't fully follow the relevant RFC - they will match the wildcard * to any domain or subdomain, for instance the list below would all match a wildcard cert issued with the common name *
  2. I.E 6 and IE 7 however follow the guidelines to the rules - these specify that a wildcard can only match one level of subdomains, so with the same common name as the previous example we get
    1. - Match
    2. - Match
    3. - The dreaded certificate error problem


The Solution

There are some custom fields in a certificate where you can specify other sites where the certificate is valid - known as "Certificate Subject Alt Name", thankfully we specify as many domain names that we want in here - but even better this field also supports wildcarding.

Initially only created one entry in this extra field - the entry I needed for a Vista Sidebar tool to connect which required a valid certificate, this however then broke compatibility with Firefox for all my other domains. It turns out that if this field is present Firefox then ignores the usual Common Name attribute which I had left as *.

There is however a resolution to allow all browsers to co-exist in a peaceful world. Simply put we can combine the best of both worlds into the Certificate Subject Name. Starting off with creating a Certificate Authority we essentially follow heeb's guide, but I have added a few steps in at the start and end

   1: #We need to set the subjectAltName, It appears that this can't be set at the command prompt.
2: nano /usr/ssl/openssl.cnf
4: #Scroll down to the [ usr_cert ] section and alter, uncomment or add in a comma separated list
5: #of all the domains, sub domains and wildcard matches you want in the form
6: subjectAltName=DNS:*,DNS:*,DNS:*,DNS:
8: #Create temporary directories
9: mkdir -p demoCA/{certs,crl,newcerts,private
10: echo 01 > demoCA/serial
11: touch demoCA/index.txt
13: #Create a new root authority.
14: #You will want to miss out this step if you ever create more certificates,
15: #as you will want to reuse the old authority
16: openssl req -new -x509 -keyout demoCA/private/cakey.pem -out demoCA/cacert.pem -days 3652
18: #Create a signing request
19: #I don't think it matter any more what we use as common name, but use * here to be safe
20: openssl req -new -keyout ./wildcard.req -out ./wildcard.req -days 3652
22: #Sign the request
23: openssl ca -policy policy_anything -out wildcard.crt -infiles wildcard.req
25: #Extract the key for Apache, it is used for encrypting/decryptind the data
26: openssl rsa <> wildcard.key
28: #Copy the file demoCA/cacert.pem into the root of all your web sites
29: #Name it with the extension .crt, for example.
30: cp demoCA/cacert.pem /path/to/website/wildcard.crt

Final Thoughts

Now simply browse to your website over http and open the file wildcard.crt that we just created When prompted to save you want to do this into the "Trusted Root" or similar folder. See below for screenshots of this process in IE and Firefox.

Note that although the steps above assume you are running Linux with Apache, there is nothing stopping you from doing this in Windows XP by using  Cygwin and importing the certificate into IIS.  In fact I made this guide using Cygwin on Windows XP and imported the certificates into Collabnet Subversion Server which is a full Apache server for Windows XP with built in svn support wrapped up in a simple installer.

The Final step is to setup multiple virtual directories in either IIS or Apache and tell them to use the key we just created, a guide for Apache can be found in my next blog post here.

Installing a new Trusted Root in Internet Explorer

Add Root CA - Explorer 3

Installing a new Trusted Root in Firefox

Add Root CA - Firefox


Vituko said...

Eres un crack, chapó colega!!
This post is so great, that i want to kiss you.
I tested my app only with firefox, the guy had only exploter and exploter didnt liked my cacert, why?, a joke? Fucking web development! Must always everything be browser specific?

Thank you very much, very clear.

dgillanas said...

Si señor!!, una idea perfecta para los certificados!!!.

Great job!!, I need create only one certificate for all my domains in my private server and never found que easy solution, but with your post work great!!!, very very nice!!! Wonderful job!!. Thank you very much!!. 4 days searching the best solution and finally found in this blog.

See you.

Click SSL said...
This comment has been removed by the author.
RapidSSLOnline said...

Excellent Peace of Writing!, We believe that your entire text in blog is truly deserved the perfect writer title. You blog stuff really will assist us to deliver the solutions for self signed certificate within cross browsers computability. Thanks sharing with US! Wildcard SSL