none
WCF Anonymous Message Security does not work with TLS 1.0 disabled RRS feed

  • Question

  • According to the release notes for .Net Framework 4.7, they indicate that applications using WCF Message-based security should now be able to support TLS 1.2:

    https://docs.microsoft.com/en-us/dotnet/framework/migration-guide/retargeting/4.0-4.7#wcf-message-security-now-is-able-to-use-tls11-and-tls12

    However, I am finding this to not be the case for my team's product, which communicates using WCF Message Security with Anonymous authentication (i.e. <message clientCredentialType="None"/>).  Once we disabled TLS 1.0 on a server in our lab environment, the communication no longer worked.  The client receives an exception stating "The request for security token could not be satisfied because authentication failed."

    I have verified the issue using the Microsoft-provided WCF samples (located here: https://www.microsoft.com/en-us/download/details.aspx?id=21459).  Specifically I tested using the .\WCF\Basic\Binding\WS\MessageSecurity\Anonymous\CS\Anonymous.sln project that was provided with those samples.

    I made changes to the sample program to have it target .Net v4.7.  I also added the following config property as prescribed by the aforementioned release notes:

    <runtime>
      <AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
    </runtime>

    Unfortunately that did not make a difference.  Are there other changes that must be made to get Anonymous Message-based security to work with TLS 1.2, or is that scenario not officially supported?


    Thanks!


    Wednesday, April 10, 2019 5:20 PM

All replies

  • Hi Dhromas,

    It seems that there is no fault in the document. here is my example, 
    Server(.net framework4.7) console application.

    static void Main(string[] args)
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                Uri uri = new Uri("http://localhost:4396");
                WSHttpBinding binding = new WSHttpBinding();
                binding.Security.Mode = SecurityMode.Message;
                binding.Security.Message.ClientCredentialType = MessageCredentialType.None;
                using (ServiceHost sh=new ServiceHost(typeof(TestService),uri))
                {
                    sh.AddServiceEndpoint(typeof(ITestService), binding, "");
                    ServiceMetadataBehavior smb;
                    smb = sh.Description.Behaviors.Find<ServiceMetadataBehavior>();
                    if (smb==null)
                    {
                        smb = new ServiceMetadataBehavior()
                        {
                            HttpGetEnabled = true
                        };
                        sh.Description.Behaviors.Add(smb);
    
                    }
    
                    Binding mexbinding = MetadataExchangeBindings.CreateMexHttpBinding();
                    sh.AddServiceEndpoint(typeof(IMetadataExchange), mexbinding, "mex");
    //provide the certificate to encrypt the message.
                    X509Certificate2 cert = new X509Certificate2("1.pfx", "123456");
                    sh.Credentials.ServiceCertificate.Certificate = cert;
    
                    sh.Opened += delegate
                    {
                        Console.WriteLine("service is ready");
                    };
                    sh.Closed += delegate
                    {
                        Console.WriteLine("service is closed");
                    };
                    sh.Open();
                    Console.ReadLine();
    
                    sh.Close();
                }
            }
        }
        [ServiceContract]
        public interface ITestService
        {
            [OperationContract]
            string GetResult();
        }
    
        [ServiceBehavior]
        public class TestService : ITestService
        {
            public string GetResult()
            {
                return $"Hello, busy World. {DateTime.Now.ToShortTimeString()}";
            }
    }
    

    Client (invocation by adding service reference, .net framework4.7)

            static void Main(string[] args)
            {
                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
                ServiceReference1.TestServiceClient client = new ServiceReference1.TestServiceClient();
                try
                {
                    var result = client.GetResult();
                    Console.WriteLine(result);
                }
                catch (Exception)
                {
                    throw;
                }
            }
    

    Before I change the following code (both server side and client side), this project works well.

    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;

    When I changed to the TLS version to tls12, it throws the client authentication errors.
    Only when I add the following code to the configuration file, it works.

      <runtime>
        <AppContextSwitchOverrides value="Switch.System.ServiceModel.DisableUsingServicePointManagerSecurityProtocols=false;Switch.System.Net.DontEnableSchUseStrongCrypto=false" />
      </runtime> 
    

    Wish the above example is useful to you.
    Feel free to let me know if there is anything I can help with.
    Best Regards
    Abraham

    Thursday, April 11, 2019 10:04 AM
    Moderator
  • Hi Abraham,

    I have some issues with Message Security and TLS 1.0. I have the same issue as Dhromas presented.

    I want to add that I disabled all comunication protocols except TLS 1.2 with IIS Crypto (from Nartac). If I leave TLS 1.0 checked the communication works, but if I only leave TLS 1.2 checked I get the following exception:

    System.ServiceModel.Security.SecurityNegotiationException: 'SOAP security negotiation failed. See inner exception for more details.

    'Inner Exception:Win32Exception: The client and server cannot communicate, because they do not possess a common algorithm


    I tried your example also, but with no success.

    Some extra details.

    I have also changed an Event Viewer registry so I can see more information. When I have TLS 1.0 checked and the test application works I can see this Information in the Event Viewer:

    A TLS client handshake completed successfully. The negotiated cryptographic parameters are as follows.
     
       Protocol version: TLS 1.0
       CipherSuite: 0x35
       Exchange strength: 2048 bits
       Context handle: 0x22a54849c00
       Target name: 
       Local certificate subject name: 
       Remote certificate subject name: CN=*********

    The frameworks I tried were .NET 4.8, 4.7, 4.7.1, 4.6


    • Edited by CPagu Tuesday, March 3, 2020 2:30 PM
    Tuesday, March 3, 2020 12:05 PM