Friday, March 28, 2008

Painless SSL On Your Desktop

I was developing a WCF solution that called for UserNameOverTransport authentication. "OverTransport" meant using SSL. Since I'm a coding/architect kind of guy, I had to dig around to find out how to get an X509 certificate installed in my local IIS so I could run SSL on it.

Creating a certificate is easy with makecert.exe, a utility that comes with the Visual Studio SDK. Getting one that works is another matter. By "works" I mean (1) you can install the certificate in IIS, (2) it will be fully trusted by WCF, and (3) you can use it with URLs containing "localhost" without hearing grief about the certificate being issued to a different name.

The keys to success turn out to be (i) installing a ginned-up "authority" into the Trusted Root Certificate Authorities store, and (2) installing a certificate issued by that "authority", in the name of "localhost", into your Personal store.

Getting makecert.exe to do these things requires a lot of fancy parameters. This fine blog post by Michael Howard explains most of what you need to do. The only shortcoming of Howard's otherwise excellent instructions is that he installs the issuer's certificate into the Personal store instead of into Trusted Root Certificate Authorities, and thus WCF won't trust it. To fix that I changed the -ss parameter from "MY" to "ROOT".

Here is text of the batch file I used to create my fully SSL-ready certificate:

@echo off

makecert.exe -r -pe -n "CN=Acme Test And Dev Root Authority" -ss ROOT -sr LocalMachine -a sha1 -sky signature "Acme Test And Dev Root Authority.cer"

makecert -pe -n "CN=localhost" -ss MY -sr LocalMachine -a sha1 -sky exchange -eku -in "Acme Test And Dev Root Authority" -is ROOT -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 localhost.cer

Once the batch file ran, I opened the IIS Admin Console and configured Default Web Site to use the certificate named "localhost" for SSL. Et voila, I can use any address on my local machine beginning with https://localhost/..., and it transports over SSL!

No comments: