Programmatic WCF Message Security with Certificates

He escrito un servicio WCF autohospedado utilizando WSHttpBindings y estoy tratando de implementar la seguridad a nivel de mensaje utilizando certificados que he generado yo mismo. Lamentablemente, recibo una excepción oculta (a través del Visor de seguimiento del servicio) que dice "No se reconocieron las credenciales proporcionadas al paquete".

Un par de notas:

Esto debe hacerse en código, no en configuración (Servidor / Cliente) Los certificados son certificados que se encuentran en la tienda de máquinas local con claves privadas accesibles para mi usuario durante la depuración. Busqué en Google todo esto y encontré un buen recurso para configurar la seguridad basada en mensajes WCFaqu

No estoy seguro de lo que me estoy perdiendo. La mayoría de estas cosas parecen sencillas, excepto para crear las identidades de punto final. Falla con el mismo mensaje si uso DnsEndpointIdentities, certificados o no tengo ninguna identidad.

¿Alguien puede señalarme en la dirección correcta?

Lado del servidor

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();

Lado del cliente

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();

Respuestas a la pregunta(1)

Su respuesta a la pregunta