Setting up your own certificate authority on IIS7 using OpenSSL and securing your web api with client certificates

Creating self signed certificates isn’t really all that complicated, but it can be a little intimidating the first time you do it.

What are we trying to achieve?

1) A web api that is protected by client certificates hosted on IIS7.
2) A way to test it out from our browser.

Why?

Well, the use case is a web api that is not open to the public. We want to secure it such that only clients with the relevant certificates can access the api.

Pre-requisites

A web site that is protected by a valid SSL certificate
OpenSSL – I installed this on a 64bit version of Win7. Be warned, you need Visual C++ 2008 redistributable installed first. Be warned, yet again, that even though open ssl should install in 64bit mode, I couldn’t get it working so I just took the 32 bit. Hasn’t done me any harm….. 🙂

Gotchas

Testing your api from a browser like IE requires you to have a p12 client certificate to import into your personal certificate store. This one caught me out for a while.

Setting up your root certificate authority

First create a key pair that you will use to sign your certificate:

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:

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 your webserver recognise your new certificate as a trusted Certificate Authority

Copy your root-ca.crt file to your webserver. Now, either double click the .crt file or if you prefer, open up a command prompt, “mmc” and follow these instructions:
* Click File->Add/Remove Snap-in
* Select “Certificates” and choose “Computer Account”.
* Expand “Trusted Root Certification Authorities” and right-mouse button, “Import”.
* Find your root-ca.crt and complete the import.

Create a website and require certificates

Create a new site or application in IIS, and then using the IIS manager, select the SSL Settings.

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.

Create a client certificate request

You’ve got your root cert. You’ve installed it on your webserver. You’ve locked down your website. All that’s left to do is create the client certificate, install it in your certificate store on the client machine and away you go.

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

Import your p12 certificate into your local personal certificate store

Again, double click the .p12 file, or go through mmc to import the p12 certificate and you should be away. Close IE, re-open and browse to your locked down website. You should be greeted with your website.

Aaaaah. That wasn’t so bad was it?

Everything I know about the command line I learned from from Tron Legacy

Just kidding…..but they did actually use real command line…um commands….and here they are.

btw, <3 you Reddit.....now on with the show:

Scene: In the Encom boardroom

Edward Dillenger, the evil wunderkind of Encom, on seeing the chaos of a barking dog video instead of the brand new Encom OS12:


ps -ef | grep -i os12

Thus he lists processes running that have a case insensitve match of the string os12.

Having found the rogue process above, Ed decides to terminate the puppy:

kill -9 17319

Scene: Sam, our hero, in his old man’s underground laire

Finding a computer covered in dust, Sam wipes it (the dust) away and a lovely futuristic looking machine under a glass worktop comes to life:

whoami

He types, asking the machine for the effective username. It tells him: “flynn”. Hmmm he thinks and then whips out a quick


uname -a

Oooh, gotta find out some operating system implementation info. The -a switch is a shortcut switch which basically means show all the info about the current OS. But this isn’t enough for our hero. He has to try and log in, doesn’t he:


login -n root

Now, he should have known better, I mean, his old man was the uber-geek genius of his generation. You can’t just login as root without a password (yes I realise there is inconsistency in the story line here with the other terminal windows open etc but still). Next up, Sam tries the “backdoor”


backdoor

because every system in the world has a “backdoor” so named that will just let us in. On password change days, I kind of wish mine did.

Now, young Sam is curious. What was the old man up to?


bin/history

Hmm….nothing to see here, cows turn themselves inside out all the time, and dad clearly works on his last_will_and_testament.txt all the time too. Let’s ignore all that and rather type in the ominous sounding LLLSDLaserControl command that was the last thing his dad typed in before disappearing off the face of the planet leaving his ‘puter all powered up and such.


LLLSDLaserControl -ok 1

Well good thing he did too because he gets zapped into the grid and we get a movie out of the deal. Great Success!