Creating self signed certificates isn't really all that complicated, but it can be a little intimidating the first time you do it.
openssl genrsa -des3 -out root-ca.key 1024
Enter a strong pass phrase. This is the most vital pass phrase you will ever come up with - your root certificate is what you will use to sign client certificates and it is what will be installed on your IIS7. Basically, if someone gets your root cert and your passphrase for it, they can create their own client certificates and your web api will trust them. If you are super paranoid, disconnect the server that you are using to create this certificate from the network forever.
Now use your key pair to create and sign a root certificate:
<code class="c">openssl req -new -x509 -days 3650 -key root-ca.key -out root-ca.crt
We are generating a certificate that will be valid for 10 years. Make it shorter if you prefer. You'll be prompted for your root key pair pass phrase and a bunch of info - fill it in, forget about the email address.
You now have a root certificate - this is what you will install on your web server. You will also use the root certificate to sign client certificate requests. Once the client certificate request has been signed by with the root certificate, any requests to your secured api with these client certificates will be implicitly trusted by your web server.
Make sure Require SSL is checked and that the Client Certificates option is set to Require.
If you try to browse your website now, you should get an access is denied message.
Open up the command prompt on your client machine which has openssl installed on it and:
openssl genrsa -out client-cert.key 1024
As above, we generate a keypair, and then create the certificate request:
openssl req -new -key client-cert.key -out client-cert.csr
Again, you'll be prompted for all sorts of information - fill it in. When you put the organisation name and common name, use something different from your root certificate above so you can keep tabs on things in your personal certificate store.
Now, we use the client certificate request and create a client certificate, signing the certificate with our root certificate:
openssl x509 -req -day 3650 -CA pathtoroot-ca.crt -CAkey pathtoroot-ca.key -CAcreateserial -in client-cert.csr -out client-cert.crt
You'll be asked for your root certificate pass phrase - you remember, the one I told you was super-important above.
Very cool, we now have a client certificate that IIS will trust because it has been signed by a root certificate that IIS trusts. Woohooo.
And here is the gotcha - If you simply install this .crt in your certificate store and try to browse your locked down website, it just will not work!
And here is the fix - see Internet Explorer needs the certificate to be in a specific format (pkcs12) for it to actually present the certificate to the webserver when you go a-browsing. Luckily, openssl allows us to fix this issue:
openssl pkcs12 -export -clcerts -in client-cert.crt -inkey client-cert.key -out client-cert.p12
Aaaaah. That wasn't so bad was it?