Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / containers / virtual-machine

Securing WCF Services with Certificates

4.93/5 (70 votes)
30 Jul 2008CPOL8 min read 1   2.7K  
An article that describes how to secure WCF services using X.509 certificates issued from a certificate authority.

Introduction

This article provides a step-by-step guide to securing WCF services with certificates. Most articles of this nature use makecert.exe to generate sample certificates. This is great for testing purposes, but what if you want to use certificates that are issued from a Certificate Authority (CA)? This article will show you how to generate certificates with Microsoft Certificate Services and use them to secure your WCF services.

Prerequisites

This article assumes that you know how to create and consume a WCF service.

You should have two separate machines to follow the steps in this article:

  1. Client machine — this can be your development system. You should have the .NET Framework 3.0 or higher installed.
  2. Server machine — this will function as our WCF server as well as a Certificate Authority. (Note that you may want to have a separate server function as the CA.) You should have Windows Server 2003 with the .NET Framework 3.0 or higher installed. If you do not have a separate machine, it is recommended that you create a virtual machine with these specifications. This can be achieved by using Virtual PC 2007.

Section 1: Install Microsoft Certificate Services on the Server

You have two options for obtaining X.509 certificates for which to secure your services:

  1. Purchase a certificate from a trusted certificate authority such as VeriSign, Thawte, RapidSSL, etc.
  2. Create your own certificate authority

This article focuses on the 2nd option by creating certificates using Microsoft Certificate Services. To install Microsoft Certificate Services, follow these instructions:

  1. On the server machine, go to Control Panel > Add or Remove Programs
  2. Select Add / Remove Windows Components
  3. Check Certificate Services and click Next to complete the installation.

    WindowsComponentsCertificateServices.jpg

  4. Select Stand-alone root CA and click Next

    WindowsComponentsCertificateServices2.jpg

  5. Fill out the CA Identifying Information

    WindowsComponentsCertificateServices3.jpg

  6. Complete the installation by accepting the remaining defaults

Section 2: Configure the client to trust the new certificate authority

Windows is preconfigured with a set of trusted certificate authorities. Of course, our new certificate authority isn't in this list. Follow these steps to allow your client machine to trust the new certificate authority.

  1. On the client machine, open a web browser and go to http://<server name>/certsrv. This will bring up a page similar to the following:

    CertificateServicesWeb1.jpg

  2. Click Download a CA certificate, certificate chain, or CRL

    CertificateServicesWeb2.jpg

  3. Click Download CA certificate chain. Save the certnew.p7b file to your file system.
  4. Load the Certificates MMC Snap-In. Note that several steps in this article will require loading this snap-in. The following instructions show how to do this, and they will not be repeated in subsequent sections.

    1. Select Start > Run and type "mmc" to open the Microsoft Management Console
    2. Select File > Add / Remove Snap-in
    3. Click the Add button
    4. Select Certificates and click the Add button
    5. Select Computer Account and click the Next button
    6. Click the Finish button
    7. Click the Close and OK buttons
  5. Expand Certificates (Local Computer) > Trusted Root Certification Authorities > Certificates

    ClientCertificates1.jpg

  6. Right-click the Certificates folder and select All Tasks > Import

    CertificateImport1.jpg

  7. Click Next, then click Browse
  8. Select PKCS #7 Certificates from the Files of type drop down list
  9. Browse to the certnew.p7b file that you saved in step 3. Click the Open button

    CertificateImport2.jpg

  10. Click Next, Next, and Finish. You should now see your CA listed as a Trusted Root Certificate Authority.

    CertificateImport3.jpg

Note: If your WCF server is different than your CA server, you will need to repeat Section 2 for the WCF server machine.

Section 3: Create a Client Certificate

This section explains how to create a certificate for our WCF client.

  1. On the client machine, open a web browser and go to http://<server name>/certsrv
  2. Click Request a certificate
  3. Click advanced certificate request
  4. Click Create and submit a request to this CA
  5. Fill out the form as shown in the image below:

    ClientCertificateRequest1.jpg

  6. Click Submit and accept the warning message. You will see a confirmation that your request has been received and is pending.

    ClientCertificateRequest2.jpg

  7. On the server, select Start > Programs > Administrative Tools > Certification Authority
  8. Expand the CA and click Pending Requests. You should see your client certificate request in the list.

    PendingRequest1.jpg

  9. Right-click the request, select All Tasks > Issue to approve the certificate
  10. On the client machine, go back to http://<server name>/certsrv
  11. Click View the status of a pending certificate request

    PendingRequest2.jpg

  12. Click the Client Authentication Certificate link and accept the warning message.

    PendingRequest3.jpg

  13. Click Install this certificate and accept the warning message.

    At this point, the certificate's public and private key are now installed on the client machine. The next step is to install the certificate's public key on the server.

  14. Load the Certificates MMC Snap-In on the client machine. Follow these instructions to load the snap-in.
  15. Expand Certificates (Local Computer) > Personal and click Certificates

    ExportClientCert1.jpg

  16. Right-click the client certificate and select All Tasks > Export
  17. In the Certificate Export Wizard, click Next, Next, Next, select a file name, Next, and Finish
  18. Copy the exported certificate file to the server
  19. Load the Certificates MMC Snap-In on the server machine. Follow these instructions to load the snap-in.
  20. Expand Certificates (Local Computer) > Personal.
  21. Right-click Certificates, select All Tasks > Import
  22. In the Certificate Import Wizard, click Next, select the file that you exported in step 17, click Next, Next, and Finish. The client's public key should now be installed on the server.

    ImportClientCert1.jpg

Section 4: Create a server certificate

Creating a server certificate is very similar to creating a client certificate, so this section doesn't contain as many screenshots as Section 3.

  1. On the server machine, open a web browser and go to http://<server name>/certsrv
  2. Click Request a certificate
  3. Click advanced certificate request
  4. Click Create and submit a request to this CA
  5. Fill out the form as shown in the image below:

    ServerCertificateRequest1.jpg

  6. Click Submit and accept the warning message. You will see a confirmation that your request has been received and is pending.
  7. On the server, select Start > Programs > Administrative Tools > Certification Authority
  8. Expand the CA and click Pending Requests. You should see your client certificate request in the list.
  9. Right-click the request, select All Tasks > Issue to approve the certificate
  10. Go back to http://<server name>/certsrv
  11. Click View the status of a pending certificate request
  12. Click the Server Authentication Certificate link and accept the warning message.
  13. Click Install this certificate and accept the warning message.
  14. Now, if you try to load your service in a browser, you would likely get an error similar to the following:

    System.Security.Cryptography.CryptographicException: Keyset does not exist
    ArgumentException: The certificate 'CN=My Server Machine' must have a private key that is capable of key exchange. The process must have access rights for the private key.

    To fix this problem, we need to give the ASPNET or NETWORK SERVICE account permission to read the certificate. This can be achieved with the following tool:

    Windows HTTP Services Certificate Configuration Tool

    Once this tool is downloaded, execute one of the following commands (depending on your server configuration).
    C:\Program Files\Windows Resource Kits\Tools>winhttpcertcfg -g -c
         LOCAL_MACHINE\My -s "My Server Machine" -a ASPNET
    C:\Program Files\Windows Resource Kits\Tools>winhttpcertcfg -g -c
         LOCAL_MACHINE\My -s "My Server Machine" -a "NETWORK SERVICE"

    At this point, the certificate's public and private key are now installed on the server machine. The next step is to install the certificate's public key on the client.

  15. Load the Certificates MMC Snap-In on the server machine. Follow these instructions to load the snap-in.
  16. Expand Certificates (Local Computer) > Personal and click Certificates

    ExportServerCert1.jpg

  17. Right-click the server certificate and select All Tasks > Export
  18. In the Certificate Export Wizard, click Next, Next, Next, select a file name, Next, and Finish
  19. Copy the exported certificate file to the client
  20. Load the Certificates MMC Snap-In on the client machine. Follow these instructions to load the snap-in.
  21. Expand Certificates (Local Computer) > Personal.
  22. Right-click Certificates, select All Tasks > Import
  23. In the Certificate Import Wizard, click Next, select the file that you exported in step 17, click Next, Next, and Finish. The server's public key should now be installed on the client.

    ImportServerCert1.jpg

Section 5: Certificate Review

We have now accomplished the following:

  • Created a Certificate Authority on the server machine
  • Trusted the Certificate Authority on the clinet machine
  • Created a client certificate on the client machine
  • Installed the client certificate's public key on the server machine
  • Created a server certificate on the server machine
  • Installed the server certificate's public key on the client machine

Section 6: WCF Service Configuration Changes

The following is the WCF service's web.config file:

ServerConfig.jpg

  1. Message security via certificates has been enabled on the custom binding.
  2. The client certificate requirements have been defined on the custom behavior. The ChainTrust value specifies that the certificate chain must be validated. The revocationMode is set to NoCheck. It is recommended that this value be set to Online in a production environment so that revoked certificates are not allowed. This requires that you have a properly configured revocation server. This is outside of the scope of this article, but the following page will point you in the right direction:

    Specify certificate revocation list distribution points in issued certificates

  3. The Location of the server certificate has been specified on the custom behavior. Note that you may want to use a more specific search method than FindBySubjectName since you may have multiple certificates with the same subject. FindByThumbprint should be sufficient for locating a unique certificate.

Section 7: WCF Client Configuration Changes

The following is the WCF client's app.config file:

ClientConfig.jpg

  1. The client is communicating with a server called myserver, but the server is identifying itself as My Server Machine (as defined in the certificate). As a workaround, we have set the dns value to My Server Machine. This is not necessary if the certificate matches the host name.
  2. The Location of the client certificate has been specified on the custom behavior.
  3. The server certificate authentication options have been defined on the custom behavior.
  4. Message security via certificates has been enabled on the custom binding.

Your client should now be able to securely communicate with the service.

Conclusion

As you can see, using WCF with certificates can be a tedious process, but there are certain scenarios that warrant this level of security. I hope this article helps you avoid some of the common pitfalls associated with this security solution.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)