Tuesday, June 3, 2008

Configuring a port for SSL/TLS

Note that what we usually refer to as SSL is now really TLS (Transport Layer Security).
--------------
If you want to use Transport Security with your http WCF service, there are two options:
  • Host your service in IIS.
  • Configure a port for SSL/TLS and self-host your web service. This will allow you to create a Windows Service that runs your web service over https.

Either way, you will need a certificate that identifies your host as trusted to the client and provides the public and private keys that are used for negotiating the encrypted transfer. For a production environment you will need to obtain the certificate from a Certificate Authority (CA).

For development and testing, we can create our own CA and then issue a test certificate from that CA. It can't be used in production because the clients will not have a trusted relationship with that CA, but we will configure our test client to trust it. You will need the MMC snap-in from my previous post. Run MMC and Open the SSL Snap-in that you previously configured. This way you will see the certificates as they are created in the Certificate Store.

You will also need the makecert.exe tool. You will have it if you have Visual Studio or the .NET Framework SDK. Go to your Start Menu and run the appropriate Command Line Environment.

Finally, you will need httpcfg.exe (download for Windows XP SP2). Vista users will use netsh.exe. This tool will be used to associate the certificate with the port.

The instructions for creating the certificate are based on Chris Jackson's post.

Create the CA certificate

At the command line (all one command),

makecert -pe -n "CN=Test and Dev Root Authority" -ss my -sr LocalMachine -a sha1 -sky signature -r "Test and Dev Root Authority.cer"

Now, if you look in the Local Computer (-sr LocalMachine) section of the SSL Certificates MMC Console, you will find a certificate in the Personal\Certificates folder (-ss my). You may need to refresh (F5) the folder.

Create the Test Certificate

Next, we will create the certificate to be assigned to the port. The name of the certificate must match the hostname in the URL that the client will use to access the service. Otherwise, the client will refuse to complete the handshake. Sometimes you get this error in your browser when the certificate name does not match the URL. Just as in the browser scenario, it is possible to configure the WCF client to ignore the mismatch, but I will leave that to a future post.

If you want to access the service via https://testserver:8081/service, enter the following at the command line (all one command),

makecert -pe -n "CN=testserver" -ss my -sr LocalMachine -a sha1 -sky exchange -eku 1.3.6.1.5.5.7.3.1 -in "Test and Dev Root Authority" -is MY -ir LocalMachine -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 "Test and Dev SSL.cer"

Again, you will find a new certificate in the Personal\Certificates folder on the Local Computer main node. If you double-click to view it you will see that it is not trusted. That is because your computer does not trust the CA certificate that we made and used to sign the testserver certificate.

Trust the CA

To trust the new CA certificate drag it from the Personal\Certificates folder to the Trusted Root Certificate Authorities\Certificates folder below it. Now if you open the testserver certificate, it will show as valid.

Configure the port for https

The last step is to configure a port (8081 in this example) to use the testserver certificate for SSL/TLS. The HTTP.SYS driver will use the certificate's thumbprint to look it up in the certificate store, so open the testserver certificate and go to the details tab. Scroll to the bottom and select the Thumbprint property. The text box below it will show the value with spaces:
71 d1 ea 2b 7d 2e cf 75 ac a5 60 1f 66 94 9b b6 ee aa be 44.

We will use the httpcfg.exe command to configure it. It is probably located in C:\Program Files\Support Tools. You will need to remove the spaces from the thumbprint hash value.

httpcfg set ssl -i 0.0.0.0:8081 -h 71d1ea2b7d2ecf75aca5601f66949bb6eeaabe44 -f 2

The -f 2 option will allow us to use client certificates to authenticte the client in a later post. The 0.0.0.0 IP address means all IP addesses on the computer. If you only want to associate it with a single IP address, use that one.

Now you can configure your service to listen on https.

No comments: