WCF Message Security Using Certificates

In this article, you will learn about WCF Message Security using certificates.

We need a valid certificate to authenticate a client and a service. Here, valid means that the certificates should be generated by a Certificate Authority. A certificate authority can be any third party certificate authority [recommended in case of production] or we can create our own certificate authority [DEV STAGE ONLY]. Once we get the Certificate Authority, we need to create different certificates for different components.

Follow the below process to create a certificate authority. I am using “makecert” for creating a certificate authority.
 
Launch Visual Studio command prompt to use makecert. The name of my certificate authority is “Dev Certification Authority”. Below is the command to create the certificate authority. It will ask to set a password, go ahead and set it. You have to remember this password as we are going to use this at the time of generating the service and the client certificates.

>>makecert -pe -sv SignRoot.pvk -cy authority -r signroot.cer -a sha1 -n "CN=Dev Certification Authority" -len 2048 -ss My -sr localmachine -sky exchange

WCF Message Security Using Certificates 

After entering the password, it gave an error to me. The reason is that I tried to execute it many times so this was already available with me. For that, we need to delete the existing key and try to create a certificate once again. Use the below mentioned two commands to delete a key.

>>DEL SignRoot.pvk

>>DEL SignRoot.cer
 
WCF Message Security Using Certificates 

Here, I have deleted the existing subject keys. Now, try to execute the certificate creation command again.

>>makecert -pe -sv SignRoot.pvk -cy authority -r signroot.cer -a sha1 -n "CN=Dev Certification Authority" -len 2048 -ss My -sr localmachine -sky exchange

It will ask you to enter a password. Enter it and go ahead.

WCF Message Security Using Certificates
 
WCF Message Security Using Certificates
 
WCF Message Security Using Certificates

Here, we have created a certificate authority successfully. To verify it, launch Run>>MMC. It will launch the Window MMC as below.

WCF Message Security Using Certificates
 
WCF Message Security Using Certificates

Click File >> Add/Remove Snap-in. It will open the "Add Snap-in" window.  Select certificate in the available snap-in list. Click Add >.

 

WCF Message Security Using Certificates

 

WCF Message Security Using Certificates

Select "Computer Account" and click "Next".

WCF Message Security Using Certificates

It will open the Console Root as below.

WCF Message Security Using Certificates

Expand certificates -Local Computer.>> Personal>> Certificates. Then, you can see the certificate which we created using the makecert command.

“Dev Certification Authority”.
 
WCF Message Security Using Certificates

Double-click that certificate to see the properties. You can see that this certificate is not trusted. We need to add this certificate in “Trusted Root Certification Authority”.

WCF Message Security Using Certificates

To do so, copy this certificate and paste in the “Trusted Root Certification Authority” field.

WCF Message Security Using Certificates

Now, go to Personal>>Certificate and then double-click the certificate. You will see the result as below. Our certificate is valid. That means now our certificate authority is a trusted certificate authority.

WCF Message Security Using Certificates

Now, let's create certificates for our service and client. My certificate authority will issue me certificates which I will use for authentication in WCF. Here, I have one service and one client. So, I will generate two certificates in my certificate authority.

Launch Visual Studio command prompt and execute the below commands. It will ask us to enter the issuer's password. Enter the password which you have entered at the time of the creation of the certificate authority.

Command for Service,

>>makecert -pe -sk ServerCert -iv SignRoot.pvk -n "CN=ServerCert" -ic signroot.cer ServerCert.cer -sr localmachine -ss My -sky exchange

Command for Client,

>>makecert -pe -sk ClientCert -iv SignRoot.pvk -n "CN=ClientCert" -ic signroot.cer ClientCert.cer -sr localmachine -ss My -sky exchange

WCF Message Security Using Certificates

Once we have executed this, it will generate certificates in Personal>>Certificates.

WCF Message Security Using Certificates

Now, we are ready with certificates.

Server Certificate

WCF Message Security Using Certificates

Client Certificate

WCF Message Security Using Certificates

Export these certificates

Now, we will export these certificates so that we can import them wherever we are going to use them.

Launch MMC Console, Personal>>Certificates>>Select Certificate>> RightClick on Dev Certificate Authority>>All Task>> Export>> Next.

WCF Message Security Using Certificates

Click Next>> Browse File to Save>>Next>>Finish. 

See the saved location for verification.

Now, we will export the Server Cert and Client Cert. But there is one additional thing. I want two different certificates of Server. One is Private key cert and another is Public key. Same for the Client Cert. So, here, I will generate 4 different certificates.I will explain at a later stage why I am creating this.

  1. Server Private Key
  2. Server Public Key
  3. Client Private Key
  4. Client Public Key

Right-click on the respective certificate and select the "Export" option and go ahead. In the Certificate Export wizard, it will give an option to export the private key or public key. We will execute it twice as we want a private key as well as a public key.

WCF Message Security Using Certificates

In the end, we will have 5 certificates.

  1. Certificate Authority certificate
  2. Server Private Key
  3. Server Public Key
  4. Client Private Key
  5. Client Public Key

Now, we want to use these certificates in WCF for message security. For that, we need to create one service and one client. We need two machines. One for running our service and one for running a client.

Certificate related operations to be performed at Server Machine

I need to import the Certificate Authority certificate at the server machine and place it in the “Trusted Root Certificate Authority” folder.

Import Servers Private key & keep a copy of it in Trusted People Folder as well as Personal Folder.

Import Client Public key & keep a copy of it only in Trusted People Folder.

Certificate related operations to be performed at Client Machine

Import Client Private Key and keep a copy of it in the Trusted People folder as well as in Personal folder.

Import Server Public key and keep a copy of it only in the Trusted People folder.

So now, we are done with placing certificates. Its time to use them in WCF service.

WCF Service Config File

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.     <startup>  
  4.         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />  
  5.     </startup>  
  6.     <system.serviceModel>  
  7.         <behaviors>  
  8.             <serviceBehaviors>  
  9.                 <behavior name="SecurityBehavior">  
  10.                     <serviceDebug includeExceptionDetailInFaults="True" />  
  11.                     <serviceCredentials>  
  12.                         <serviceCertificate findValue="ServerCert" storeLocation="CurrentUser" storeName="My" x509FindType="FindBySubjectName" />  
  13.                         <clientCertificate>  
  14.                             <authentication certificateValidationMode="PeerTrust" trustedStoreLocation="LocalMachine" revocationMode="NoCheck"  
  15. mapClientCertificateToWindowsAccount="false" />  
  16.                         </clientCertificate>  
  17.                     </serviceCredentials>  
  18.                 </behavior>  
  19.             </serviceBehaviors>  
  20.         </behaviors>  
  21.         <services>  
  22.             <service name="SampleWCFServiceLibrary.Service1" behaviorConfiguration="SecurityBehavior">  
  23.                 <endpoint address="Service1" binding="netTcpBinding" contract="SampleWCFServiceLibrary.IService1" bindingConfiguration="SecuredBinding"></endpoint>  
  24.                 <host>  
  25.                     <baseAddresses>  
  26.                         <add baseAddress="net.tcp://192.168.1.48:8798"/>  
  27.                     </baseAddresses>  
  28.                 </host>  
  29.             </service>  
  30.         </services>  
  31.         <bindings>  
  32.             <netTcpBinding>  
  33.                 <binding name="SecuredBinding" >  
  34.                     <security mode="Message">  
  35.                         <message clientCredentialType="Certificate" ></message>  
  36.                     </security>  
  37.                 </binding>  
  38.             </netTcpBinding>  
  39.         </bindings>  
  40.     </system.serviceModel>  
  41. </configuration>  

Client’s Config File

  1. <?xml version="1.0" encoding="utf-8" ?>  
  2. <configuration>  
  3.     <startup>  
  4.         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />  
  5.     </startup>  
  6.     <system.serviceModel>  
  7.         <bindings>  
  8.             <netTcpBinding>  
  9.                 <binding name="NetTcpBinding_IService1" closeTimeout="00:01:00"  
  10. openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"  
  11. maxReceivedMessageSize="65536"  
  12. maxBufferPoolSize="524288" >  
  13.                     <security mode="Message">  
  14.                         <message clientCredentialType="Certificate" />  
  15.                     </security>  
  16.                 </binding>  
  17.             </netTcpBinding>  
  18.         </bindings>  
  19.         <client>  
  20.             <endpoint address="net.tcp://192.168.1.48:8798/Service1" binding="netTcpBinding" behaviorConfiguration="endpointCredentialBehavior"  
  21. bindingConfiguration="NetTcpBinding_IService1" contract="ServiceReference1.IService1"  
  22. name="NetTcpBinding_IService1">  
  23.                 <identity>  
  24.                     <dns value="ServerCert" />  
  25.                 </identity>  
  26.             </endpoint>  
  27.         </client>  
  28.         <behaviors>  
  29.             <endpointBehaviors>  
  30.                 <behavior name="endpointCredentialBehavior">  
  31.                     <clientCredentials>  
  32.                         <clientCertificate findValue="ClientCert"  
  33. storeLocation="CurrentUser"  
  34. storeName="My"  
  35. x509FindType="FindBySubjectName" />  
  36.                         <serviceCertificate >  
  37.                             <authentication certificateValidationMode="PeerTrust"/>  
  38.                         </serviceCertificate>  
  39.                     </clientCredentials>  
  40.                 </behavior>  
  41.             </endpointBehaviors>  
  42.         </behaviors>  
  43.     </system.serviceModel>  
  44. </configuration>  

You need to change binding address according to your machine's IP.

I have attached the source code of service as well as the client. Compile it and run it.