1

I have a WCF service that currently accepts a certificate with MD5 encryption (TLS 1.1 compatible), and a client that is able to work with that service using the above certificate.

However, we wish to upgrade to TLS1.2 with a new certificate (SHA-1 encrpytion) and be able to accept both certificates for backwards compatibility.

Is there any way this could be made possible?

The WCF service is configured in a config file as follows:

<system.serviceModel>
<services>
  <service name="MyService" behaviorConfiguration="ServiceBehavior">
    <host>
      <baseAddresses>
        <add baseAddress="net.Tcp://localhost:8004" />
        <add baseAddress="http://localhost:8006" />
      </baseAddresses>
    </host>
    <!-- Service Endpoints -->
    <endpoint address="SomeService" binding="netTcpBinding" bindingConfiguration="netTcpBindingConf" contract="IService">
      <identity>
        <dns value="ServerCertificate" />
      </identity>
    </endpoint>
    <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
  </service>
</services>
<client>
  <endpoint address="net.Tcp://localhost:8001/AnotherService" behaviorConfiguration="ClientBehavior" binding="netTcpBinding" bindingConfiguration="netTcpBindingConf" contract="IService" name="IRACService">
    <identity>
      <dns value="ServerCertificate" />
    </identity>
  </endpoint>
</client>
<behaviors>
  <serviceBehaviors>
    <behavior name="ServiceBehavior">
      <!-- To avoid disclosing metadata information, set the value below to false and remove the metadata endpoint above before deployment -->
      <serviceMetadata httpGetEnabled="false" />
      <!-- 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>
        <serviceCertificate findValue="ServerCertificate" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
        <clientCertificate>
          <certificate findValue="ClientCertificate" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" />
        </clientCertificate>
      </serviceCredentials>
      <serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="1000" maxConcurrentSessions="1000" />
      <dataContractSerializer maxItemsInObjectGraph="2147483647" />
    </behavior>
  </serviceBehaviors>
  <endpointBehaviors>
    <behavior name="ClientBehavior">
      <clientCredentials>
        <clientCertificate findValue="ClientCertificate" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
        <serviceCertificate>
          <defaultCertificate findValue="ServerCertificate" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" />
        </serviceCertificate>
      </clientCredentials>
    </behavior>
  </endpointBehaviors>
</behaviors>
<bindings>
  <netTcpBinding>
    <binding name="netTcpBindingConf" closeTimeout="00:11:00" receiveTimeout="00:10:00" sendTimeout="00:10:00" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" maxBufferSize="2147483647" maxConnections="1000" openTimeout="00:20:00">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      <reliableSession ordered="true" inactivityTimeout="00:15:00" />
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="Certificate" algorithmSuite="Default" />
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
      </security>
    </binding>
  </netTcpBinding>
</bindings>

The client is configured in a config file as follows:

  <system.serviceModel>
<bindings>
  <netTcpBinding>
    <binding name="bindingConfigName" closeTimeout="00:10:00" openTimeout="00:40:00" receiveTimeout="00:32:00" sendTimeout="00:10:00" transactionFlow="false" hostNameComparisonMode="StrongWildcard" maxBufferPoolSize="524288" maxReceivedMessageSize="2147483647">
      <readerQuotas maxDepth="2147483647" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
      <reliableSession ordered="true" inactivityTimeout="00:10:00" />
      <security mode="TransportWithMessageCredential">
        <message clientCredentialType="Certificate" algorithmSuite="Default" />
        <transport clientCredentialType="Windows" protectionLevel="EncryptAndSign" />
      </security>
    </binding>
  </netTcpBinding>
</bindings>
<client>
  <endpoint address="net.Tcp://localhost:8004/SomeService" behaviorConfiguration="ClientBehavior" binding="netTcpBinding" bindingConfiguration="bindingConfigName" contract="IService" name="ISomeService">
    <identity>
      <dns value="ServerCertificate" />
    </identity>
  </endpoint>
  <endpoint address="net.Tcp://localhost:8004/SomeService" behaviorConfiguration="ClientBehavior" binding="netTcpBinding" bindingConfiguration="bindingConfigName" contract="IService" name="ISomeService2">
    <identity>
      <dns value="ServerCertificate" />
    </identity>
  </endpoint>
</client>
<behaviors>
  <endpointBehaviors>
    <behavior name="ClientBehavior">
      <clientCredentials>
        <clientCertificate findValue="ClientCertificate" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
        <serviceCertificate>
          <defaultCertificate findValue="ServerCertificate" storeLocation="LocalMachine" storeName="My" x509FindType="FindBySubjectName" />
          <authentication certificateValidationMode="PeerOrChainTrust" revocationMode="NoCheck" />
        </serviceCertificate>
      </clientCredentials>
      <dataContractSerializer maxItemsInObjectGraph="2147483647" />
    </behavior>
  </endpointBehaviors>
</behaviors>

Tomer Something
  • 770
  • 1
  • 10
  • 24
  • Have you checked this answer? - https://stackoverflow.com/a/49164922/2858407 – stop-cran Jul 29 '19 at 07:32
  • @stop-cran this answer is not relevant to me, as i am able to work with TLS1.2 if i simply change the certificate and enable TLS1.2 (using registry) on both client and server, and i require to be able to use both TLS1.1 and TLS1.2 simultaneously depending on the client – Tomer Something Jul 29 '19 at 07:35

1 Answers1

0

TLS version that the communication actually use depends on the runtime of the application and OS version.
https://learn.microsoft.com/en-us/dotnet/framework/network-programming/tls
If possible, we could specify the TLS version with below code segment (this requires some of the prerequisites described in the above link).

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

I do not recommend this, as mentioned in the document. We just need to make sure that the application runs over Dotnet framework4.7, OS win7 above, TLS version will take precedence over the new TLS version.

Abraham Qian
  • 7,117
  • 1
  • 8
  • 22