When working with WCF you will inevitably bump your head against certificates. Microsoft has configured WCF to be secure by default, obviously this is a good thing but for an internal WCF service that is not exposed to the internet this can be overkill. Depending on your security requirements/setup you may be need to create a certificate. You can create a test X.509 certificate my using the makecert
tool, here is one for a certificate with a display name of Habanero: makecert.exe -sr LocalMachine -ss MY -a sha1 -n "CN=Habanero" -sky exchange –pe
What this does is add a private and public key to your local machine. You can verify the public key in the Certificates console:
- Select Start->Run->mmc
- In the Console select File -> Add/Remove Snap-in? -> Add -> Certificate
- Select the Computer account -> Next -> Local computer -> Finish
- Expand the Personal folder and your newly created certificate will be listed there.
The private key is stored in the folder: C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys
You will need to add read access to the Network Service account (or the identity account set on the application pool in IIS) on this folder. Note: The Administrator account only has special permissions (can add, but not edit existing) on this folder. As a result you will see some errors "Can't create key of the subject" if you run the above command multiple times. Now that we have created the certificate we want to use the same certificate in our QA and Production environments. To export the certificate to a file:
- In the Certificates console right click on the Certificate select All Tasks -> Export
- Select Yes, export the private key -> and follow the default prompts.
Now you have a certificate you can take to your other servers. To import, in the Certificates console, under Personal right click on Certificates and select Import? and follow the prompts. In your WCF Service you will need to add the following to your serviceBehaviour in your web.config
<serviceCertificate findValue="Habanero" storeLocation="LocalMachine"
storeName="My" x509FindType="FindBySubjectName" />
Note that storeName="My" maps to the the Personal certificate store. Because we are using the makecert tool to create a certificate, the certificate is not trusted and you will get an exception: "The X.509 certificate CN=Habanero chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider."
To fix this in your client application you can turn off certificate validation by setting the behaviour endpoint certificateValidationMode = "None". Your WCF client app.config would looks something similar to the following:
<endpoint address="http://localhost/Habanero.WcfServices/Service1.svc" binding="wsHttpBinding"
<authentication certificateValidationMode="None" />