2

I've created an app that has machines talking to each other across the net. I'd like to use NetTCPBinding and encrypt the messages. However I don't want or need certificates or windows authentication. I try to set the security mode to Message to get encryption and transport security to none to avoid the certificates/windows authentication but still I get:

System.ServiceModel.Security.SecurityNegotiationException: The caller was not authenticated by the service. ---> System.ServiceModel.FaultException: The request for security token could not be satisfied because authentication failed.

Here's the relevant code:

NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
razlebe
  • 7,134
  • 6
  • 42
  • 57
DaveO
  • 1,909
  • 4
  • 33
  • 63
  • See http://stackoverflow.com/questions/1570939/wcf-message-security-without-certificate-and-windows-auth – Cocowalla Aug 25 '11 at 11:40
  • Why? This seems like an unusual goal - there's little point in encryption if the attacker can just splice himself in between your two endpoints. This would just be fake security. I recommend you use transport security with a server certificate for most basic encryption needs (HTTPS-style approach). – Sander Aug 25 '11 at 12:19
  • @Sander - is there a way to do this so a downloadable desktop application can be installed via an installer on a user's machine without them having to do anything or know about certificates, or having to generate certificates for each install? – DaveO Aug 27 '11 at 07:32

2 Answers2

4

An answer from this question works: selfhosting wcf server - load certificate from file instead of certificate store

My code:

var certificate = new X509Certificate2("cert.pfx", "");

host = new ServiceHost(MessageProvider, address);
host.Credentials.ServiceCertificate.Certificate = certificate;
host.Credentials.ClientCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;

NetTcpBinding binding = new NetTcpBinding();
binding.Security.Mode = SecurityMode.Message;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;
binding.Security.Transport.ClientCredentialType = TcpClientCredentialType.Certificate;
host.AddServiceEndpoint(typeof(IService), binding, address);
host.Open();
Community
  • 1
  • 1
DaveO
  • 1,909
  • 4
  • 33
  • 63
1

I think this is what you are looking for: Message Security with an Anonymous Client. I suppose the problem in your case is that your service is not specifying a certificate on server-side:

Initial negotiation requires server authentication, but not client authentication

So when instantiating the service try to do something like (from MSDN):

myServiceHost.Credentials.ServiceCertificate.SetCertificate(
     StoreLocation.LocalMachine,
     StoreName.My,
     X509FindType.FindByThumbprint,
     "00000000000000000000000000000000");
as-cii
  • 12,819
  • 4
  • 41
  • 43