Software Security WCF Messages with Certificates

I wrote a self-service WCF service using WSHttpBindings, and I'm trying to implement message-level security using certificates that I created myself. Unfortunately, I get a hidden exception (through the Service Trace Viewer) that states: "The credentials provided in the package were not recognized."

A few notes:

  • This should be done in code, not in configuration.
  • (Server / Client) Certificates are certificates that are in the local store with available private keys for mine during debugging.
  • I searched the hell out of this and found a good resource for creating WCF based security here

I'm not sure what I am missing. Most of this material seems straightforward, with the exception of creating endpoint identifiers. It crashes with the same message, whether I use DnsEndpointIdentities, cert based, or not identify at all.

Can someone point me in the right direction?

Server side:

var binding = new WSHttpBinding { Security = { Mode = SecurityMode.Message, Message = { ClientCredentialType = MessageCredentialType.Certificate, AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256Rsa15 } } }; _host = new ServiceHost(this) { Credentials = { ServiceCertificate = { Certificate = ServiceCert }, ClientCertificate = { Certificate = ClientCert, Authentication = { TrustedStoreLocation = StoreLocation.LocalMachine, RevocationMode = X509RevocationMode.NoCheck, CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust } } } }; var address = new Uri(string.Format(@"http://serviceaddress")); var ep = _host.AddServiceEndpoint(typeof (IService), binding, address); ep.Address = new EndpointAddress(address, EndpointIdentity.CreateX509CertificateIdentity(ServiceCert)); _host.Open(); 

Client side:

 var binding = new WSHttpBinding { Security = { Mode = SecurityMode.Message, Message = { ClientCredentialType = MessageCredentialType.Certificate, AlgorithmSuite = SecurityAlgorithmSuite.Basic256Sha256Rsa15 } } }; var address = new Uri(@"http://serviceaddress"); var endpoint = new EndpointAddress(address, EndpointIdentity.CreateX509CertificateIdentity(ServerCert)); var channelFactory = new ChannelFactory<IService>(binding, endpoint) { Credentials = { ServiceCertificate = { DefaultCertificate = ServerCert, Authentication = { RevocationMode = X509RevocationMode.NoCheck, TrustedStoreLocation = StoreLocation.LocalMachine, CertificateValidationMode = X509CertificateValidationMode.PeerOrChainTrust } }, ClientCertificate = { Certificate = ClientCert } } }; var channel = channelFactory.CreateChannel(); 
+8
wcf x509certificate
source share
1 answer

this msdn article helped a lot. I think the root of the problem was setting the following message security settings to false:

 httpBinding.Security.Message.NegotiateServiceCredential = false; httpBinding.Security.Message.EstablishSecurityContext = false; 

So, now the common code for the server side is more like:

 var httpBinding = new WSHttpBinding(SecurityMode.Message); httpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; httpBinding.Security.Message.NegotiateServiceCredential = false; httpBinding.Security.Message.EstablishSecurityContext = false; var httpUri = new Uri("http://serviceaddress"); _host = new ServiceHost(this, httpUri); _host.Credentials.ServiceCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, serverThumbprint); _host.Credentials.ClientCertificate.Authentication.RevocationMode = X509RevocationMode.NoCheck; _host.Credentials.ClientCertificate.Authentication.TrustedStoreLocation = StoreLocation.LocalMachine; _host.AddServiceEndpoint(typeof(IMetaService), httpBinding, httpUri); _host.Open(); 

and client side:

 var httpBinding = new WSHttpBinding(SecurityMode.Message); httpBinding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate; httpBinding.Security.Message.NegotiateServiceCredential = false; httpBinding.Security.Message.EstablishSecurityContext = false; var httpUri = new Uri("http://serviceaddress"); var httpEndpoint = new EndpointAddress(httpUri, EndpointIdentity.CreateDnsIdentity("name of server cert")); var newFactory = new ChannelFactory<IMetaService>(httpBinding, httpEndpoint); newFactory.Credentials.ClientCertificate.SetCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "client certificate thumbprint"); newFactory.Credentials.ServiceCertificate.SetDefaultCertificate(StoreLocation.LocalMachine, StoreName.TrustedPeople, X509FindType.FindByThumbprint, "server certificate thumbprint"); var channel = newFactory.CreateChannel(); 
+11
source share

All Articles