none
WCF Message Level Security using Certificate (X.509) Message Signed and Encrypted RRS feed

  • Question


  • Hi Everybody

    I have a common use case to implement a web service (WCF) and a web client which is consuming this web service. Both Client and Service are sending and receiving Signed and Encrypted messages (Message Level Security).

    I can have multiple clients those are using my service, hence multiple client certificate need to be installed on Server where Service project is running.

    I have installed 2 Certificates (Service Certificate and Client Certificate) in local machine store under personal and trusted root certification authorities.

    makecert -sr LocalMachine -ss My -a sha1 -n "CN=WCFServer" -len 2048 -sky exchange -pe

    makecert -sr LocalMachine -ss My -a sha1 -n "CN=WCFClient" -len 2048 -sky exchange -pe
    Although Certificate give me error of "integrity of licence can not be guaranteed" but now i dont care about this issue.

    Web Client need to Sign the request message through its own Private Key and Encrypt message through Service Certificate Public key.

    Service receive the request and verify the signature of message through client Public Key and Decrypt the contents through own Private Key

    Than process the request and create a response object. Now Service must sign the response by own private key and encrypt the message through client public key.

    Now client get Signed and Encrpted response. Now it verify the response through Service Public Key and Decrypt the message by its own private key.

    This is whole Szenerio . I have installed both(Client and Service) X.509 Certificates on my local development machine. I am using wsHttpBinding and communication is working fine.

    I am using

    [ServiceContract(ProtectionLevel=ProtectionLevel.EncryptAndSign)] 
    for ServiceContract and

    [OperationContract(ProtectionLevel = ProtectionLevel.EncryptAndSign, IsOneWay = false)]
    for OperationContract.

    I have following question: do i need to Sign and Encrypt/Decrypt Request or Response message in my Code (once in client and once in service code) or Configurations in web.config on Service Project and Client project are enough to do all this stuff?


    Can any one tell me, do i need to do all this stuff in code or its done through my current configurations.

    Thanks in advance.


    Thursday, April 21, 2016 2:23 PM

Answers

  • Hello,

    It seems that you are still not clear about the steps for the certificate authentication, then please check the following steps about how to implement the certificate authentication:

    1. Create Self signed certificates for Client and Server.

    2. Export Client Certificate for Installation on Client machine.

    3. Export Server Certificate for Installation on Server machine.

    4. Install the Client Certificate on the Client machines.

    5. Add the Client Certificate to the Trusted Root Certification Authorities on the client machines.

    6. Install the Server Certificate on the Server machine.

    7. Add the Server Certificate to the Trusted Root Certification Authorities on the Server machine.

    8. Export the Server’s Public key of the Server Certificate.

    9. Establish Trust for the Server’s Public key on the Client Machine.

    10. Export the Client’s Public key of the Client Certificate.

    11. Establish Trust for the Client’s Public key on the Server Machine.

    12. Enable Transport Layer security on the Web Site in Microsoft Internet Information Server (IIS).

    13. Service Layer configuration for enabling the certificates for Mutual Authentication, Transport & Message level security.

    14. Client side configuration for enabling the certificates for Mutual Authentication, Transport & Message level security.

    For more information, please try to refer to the following article:
    https://blogs.msdn.microsoft.com/ashishme/2009/05/06/windows-communication-foundation-wcf-transport-message-security-and-mutual-authentication-using-certificates/ .

    >>1. I have multiple clients (external web applications ) which will access my service. do each client need to create their own certificate? client will deliver us certificate without private key which need to be install on Service Host server? is this a correct way?
    All the clients need to install the client certificate.
    Yes, we need to establish Trust for the Client’s Public key on the Server Machine. For the detailed information about how to implement it, please check the following article:
    https://blogs.msdn.microsoft.com/ashishme/2009/05/06/windows-communication-foundation-wcf-transport-message-security-and-mutual-authentication-using-certificates/ .

    >>2. Each client certificate need to be configured in web.config ?
    Yes, the client certificate need to be configured in the config file.

    >>3. I need to export my service certificate without private key and send to clients. clients must install and configure certificate on their application server? is this correct?
    Yes, we need to establish Trust for the Server’s Public key on the Client Machine. For the detailed information about how to implement it, please check the following article:
    https://blogs.msdn.microsoft.com/ashishme/2009/05/06/windows-communication-foundation-wcf-transport-message-security-and-mutual-authentication-using-certificates/ .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Thursday, April 28, 2016 2:19 PM
    Moderator

All replies

  • Hello,

    >>do i need to Sign and Encrypt/Decrypt Request or Response message in my Code (once in client and once in service code) or Configurations in web.config on Service Project and Client project are enough to do all this stuff?

    If we have configured the service to use the certificate authentication in the config file, then as you said all the response and request message will be Encrypted/Decrypted by the client certficate's private key/ public key and service certificate's private key/ public key. So in my mind it is enough to do all the stuff in the configure file.

    For more information, please try to refer to the following articles:
    #Certificate authentication:
    https://msdn.microsoft.com/en-us/library/ff648360.aspx .
    #Message and Transport Security:
    https://msdn.microsoft.com/en-us/library/ff648863.aspx .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Monday, April 25, 2016 3:10 AM
    Moderator
  • Thanks for your quick feedback and useful links. I will go through these links. i have few more questions which may be you can answer me.

    1. I have multiple clients (external web applications ) which will access my service. do each client need to create their own certificate? client will deliver us certificate without private key which need to be install on Service Host server? is this a correct way?

    2. Each client certificate need to be configured in web.config ?

    3. I need to export my service certificate without private key and send to clients. clients must install and configure certificate on their application server? is this correct?

    I ll be thankful for you feedback

    regards

    Monday, April 25, 2016 7:51 AM
  • Hello,

    It seems that you are still not clear about the steps for the certificate authentication, then please check the following steps about how to implement the certificate authentication:

    1. Create Self signed certificates for Client and Server.

    2. Export Client Certificate for Installation on Client machine.

    3. Export Server Certificate for Installation on Server machine.

    4. Install the Client Certificate on the Client machines.

    5. Add the Client Certificate to the Trusted Root Certification Authorities on the client machines.

    6. Install the Server Certificate on the Server machine.

    7. Add the Server Certificate to the Trusted Root Certification Authorities on the Server machine.

    8. Export the Server’s Public key of the Server Certificate.

    9. Establish Trust for the Server’s Public key on the Client Machine.

    10. Export the Client’s Public key of the Client Certificate.

    11. Establish Trust for the Client’s Public key on the Server Machine.

    12. Enable Transport Layer security on the Web Site in Microsoft Internet Information Server (IIS).

    13. Service Layer configuration for enabling the certificates for Mutual Authentication, Transport & Message level security.

    14. Client side configuration for enabling the certificates for Mutual Authentication, Transport & Message level security.

    For more information, please try to refer to the following article:
    https://blogs.msdn.microsoft.com/ashishme/2009/05/06/windows-communication-foundation-wcf-transport-message-security-and-mutual-authentication-using-certificates/ .

    >>1. I have multiple clients (external web applications ) which will access my service. do each client need to create their own certificate? client will deliver us certificate without private key which need to be install on Service Host server? is this a correct way?
    All the clients need to install the client certificate.
    Yes, we need to establish Trust for the Client’s Public key on the Server Machine. For the detailed information about how to implement it, please check the following article:
    https://blogs.msdn.microsoft.com/ashishme/2009/05/06/windows-communication-foundation-wcf-transport-message-security-and-mutual-authentication-using-certificates/ .

    >>2. Each client certificate need to be configured in web.config ?
    Yes, the client certificate need to be configured in the config file.

    >>3. I need to export my service certificate without private key and send to clients. clients must install and configure certificate on their application server? is this correct?
    Yes, we need to establish Trust for the Server’s Public key on the Client Machine. For the detailed information about how to implement it, please check the following article:
    https://blogs.msdn.microsoft.com/ashishme/2009/05/06/windows-communication-foundation-wcf-transport-message-security-and-mutual-authentication-using-certificates/ .

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.


    Thursday, April 28, 2016 2:19 PM
    Moderator
  • Hi Amy

    Thanks a lot for such a detail answer. I understand it. Now i will go through step by step guide given above. I ll let you know if i Need and further assistance.

    Kind regards

    Friday, April 29, 2016 8:42 AM
  • Hi Everybody

    I have created a service and a web client. I also have created Certificate as you described above in step by step guide. Certificates are installed on Client and Server accordingly. 

    Now communication between Client and Server is working fine. As i want to see the capture traffic via Fiddler to check either my messages are Sigend and Encrypted, i come accoss following results.

    1. Use wsHttpBinding with security mode "TransportWithMessageCredential", in fiddler messages are signed but not encrypted.

    2. When i cange security mode both on client and server to "Message" and endpoint address without SSL, Fiddler Request and response are both encrypted.

    But in this case i cant call server via SSL. I want that my Server/Service must be called through HTTPS and Messages must be encrypted.

    Is it possible in WCF?

    How to do that?

    below are my client and server configuration.

    Client Configurations:

     <system.serviceModel>
        <diagnostics>
          <messageLogging logEntireMessage="true" logMalformedMessages="false" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" maxMessagesToLog="3000" maxSizeOfMessageToLog="20000"/>
        </diagnostics>
        <client>      
          <endpoint address="https://xxxxxxxx/X509CertService/Service1.svc" binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IService1" contract="ServiceReference1.IService1" name="WSHttpBinding_IService1" behaviorConfiguration="wsHttpEndpointBehavior"/>
          
        </client>
        <bindings>
          <wsHttpBinding>
            <binding name="WSHttpBinding_IService1" closeTimeout="00:01:00" openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00" bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="65536" messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true">
              <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384" maxBytesPerRead="4096" maxNameTableCharCount="16384"/>
              <reliableSession ordered="true" inactivityTimeout="00:10:00"/>
              <security mode="TransportWithMessageCredential">
                <transport clientCredentialType="Certificate"/>
                <message clientCredentialType="Certificate" negotiateServiceCredential="true"/>
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
        <behaviors>
          <endpointBehaviors>
            <behavior name="wsHttpEndpointBehavior">
              <clientCredentials>
                <clientCertificate findValue="dd 1f 9e 8e d0 b2 c3 9a be 47 25 34 6b 43 89 98 c3 d0 40 c6" x509FindType="FindByThumbprint" storeLocation="LocalMachine" storeName="My"/>
                <serviceCertificate>            
                  <authentication certificateValidationMode="PeerTrust"/>
                </serviceCertificate>
              </clientCredentials>
            </behavior>
          </endpointBehaviors>
        </behaviors>
      </system.serviceModel>


    Server Configuration:

    <system.serviceModel>
        <diagnostics>
          <messageLogging logEntireMessage="true" logMalformedMessages="false" logMessagesAtServiceLevel="true" logMessagesAtTransportLevel="false" maxMessagesToLog="3000" maxSizeOfMessageToLog="20000"/>
        </diagnostics>
        <services>
          <service behaviorConfiguration="WCFServiceCertificate.Service1Behavior" name="WCFServiceCertificate.Service1">
            <endpoint address="" binding="wsHttpBinding" bindingConfiguration="wsHttpEndpointBinding" contract="WCFServiceCertificate.IService1"/>
            <endpoint address="mex" binding="mexHttpsBinding" contract="IMetadataExchange"/>
          </service>
        </services>
        <behaviors>
          <serviceBehaviors>
            <behavior name="WCFServiceCertificate.Service1Behavior">
              <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
              <serviceMetadata httpGetEnabled="true"/>
              <!-- To receive exception details in faults for debugging purposes, set the value below to true.  Set to false before deployment to avoid disclosing exception information -->
              <serviceDebug includeExceptionDetailInFaults="true"/>
              <serviceCredentials>
                <clientCertificate>
                  <certificate findValue="dd 1f 9e 8e d0 b2 c3 9a be 47 25 34 6b 43 89 98 c3 d0 40 c6" x509FindType="FindByThumbprint" storeLocation="LocalMachine" storeName="TrustedPeople"/>
                </clientCertificate>
                <serviceCertificate findValue="19 a9 ee 2c 5c 78 a5 a4 6c 50 4f a5 37 1c 28 d4 4d b3 3f e3" storeLocation="LocalMachine" storeName="My" x509FindType="FindByThumbprint"/>
              </serviceCredentials>
            </behavior>
          </serviceBehaviors>
        </behaviors>
        <bindings>
          <wsHttpBinding>
            <binding name="wsHttpEndpointBinding">
              <security mode="TransportWithMessageCredential">
                <transport clientCredentialType="Certificate"/>
                <message clientCredentialType="Certificate" negotiateServiceCredential="true"/>
              </security>
            </binding>
          </wsHttpBinding>
        </bindings>
      </system.serviceModel>

    Is there any thing wrong with my Configuration? My Service Message Logging also give me Plaintext messages (Not Encrypted).

    I ll be happy if you can answer me one more thing.

    In Client Configurations i just have client certificate and for Service just authentication "PeerTrust". I know i have installed Service public key certificate in trusted people of client machine. but how does client know which certificate service has? Should one not provide Service defaultCertificate or scopedCertificate?

    Thanks in advance

    regards


    • Edited by sezanawa Monday, May 9, 2016 6:21 AM
    Tuesday, May 3, 2016 9:56 AM
  • Hallo MSDN Community

    Any one here who can answer me above questions. I read a stackoverflow thread where somebody mentioned "TransportWithMessageCredential" does not provide end-to-end security.

    http://stackoverflow.com/questions/28186833/wcf-security-difference-between-transportwithmessagecredential-and-message-secu/37111147#37111147

    For End-to-End security we need to use security mode "Message".

    but the problem with Security mode Message is that i cant use it with SSL together. From Client end when i call service with security mode Message and Service URL with HTTPS, it throw error like HTTP instead of Https expected.

    question is, how can i use Transport and Message security together to have point-to-point and End-to-End security all in one?

    I want to use two different certificate, one for Transport (Issed by: CA Certificate) and one for Message security (Issued by: self created / Self signed). 

    Thanks in advance


    • Edited by sezanawa Monday, May 9, 2016 8:49 AM
    Monday, May 9, 2016 8:48 AM
  • Hello,

    >>For End-to-End security we need to use security mode "Message"

    The Message security mode provides the End-to-End security, while the Transport security mode provides the Point-to-Point security, for more information, please try to refer to the following article:
    #Message and Transport Security:
    https://msdn.microsoft.com/en-us/library/ff648863.aspx .

    >>but the problem with Security mode Message is that i cant use it with SSL together. From Client end when i call service with security mode Message and Service URL with HTTPS, it throw error like HTTP instead of Https expected.

    Yes, if you want to use the SSL with the Message Security mode, you have to use the TransportWithMessageCredential security mode, for more information, please try to refer to:
    #WS Transport With Message Credential:
    https://msdn.microsoft.com/en-us/library/aa354508(v=vs.110).aspx .

    >>question is, how can i use Transport and Message security together to have point-to-point and End-to-End security all in one?I want to use two different certificate, one for Transport (Issed by: CA Certificate) and one for Message security (Issued by: self created / Self signed). 

    In WCF we can set the Both security mode, but this security mode is only supported in the MSMQ.

    Best Regards,
    Amy Peng


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    Tuesday, May 10, 2016 2:27 AM
    Moderator
  • Hi Amy

    Thanks for your reply. Can you please answer me about my question in second last post where i have posted my configurations.

    Question is: I am using TransportWithMessageCredential but my message body in WCF Service Logs (System.ServiceModel.MessageLogging or System.ServiceModel) or in Fiddler not encrypted?

    where can i trace either my request/response messages (DataContract) are encrypted when they leave from client or server?

    Thanks & regards

    Tuesday, May 10, 2016 11:53 AM
  • Hallo Everybody

    On my above question, i found out that TransportWithMessageCredential provide only authentication at the message level where message protection happend on transport level. So WCF MessageLogging or ServiceModel Logging will log message before it has been encrypted or after it has been decrypted. 

    if this is true, it means that message contents are visible for man-in-the-middle-attacker. if he change the message contents and try to send it to final destination (server) it will not be accepted by server because message signature is not more valid. Can any one from community confirm my statement?

    If this all is true, that sensitive informations are visible for man-in-middle-attack. it means TransportWithMessageCredential  is not the right security mode to protect messages ?

    I ll be happy for any answer.

    regards


    • Edited by sezanawa Thursday, May 19, 2016 10:58 AM
    Thursday, May 19, 2016 9:53 AM