简体   繁体   English

WCF传输安全性,具有匿名访问权限的消息加密

[英]WCF Transport Security, Message Encryption with Anonymous Access

I'm trying to setup a WCF client to talk with a service. 我正在尝试设置WCF客户端以与服务对话。 The connection needs to be https (Transport Security) and we need to do message encryption with a public key. 连接必须为https(传输安全性),并且我们需要使用公共密钥进行消息加密。 We do not have a client certificate to present. 我们没有要提供的客户证书。

var binding = new WSHttpBinding();
binding.Security.Mode = SecurityMode.Transport;
// This is failing because the private key for client authentication is not being set
// binding.Security.Mode = SecurityMode.TransportWithMessageCrediential;
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Message.ClientCredentialType = MessageCredentialType.Certificate;

And then to set the public key I'm doing 然后设置我正在做的公钥

client.ClientCredentials.ServiceCertificate.DefaultCertificate = certificate;

Where certificate is an X509Certificate2 object with just the public key. 证书是带有公共密钥的X509Certificate2对象。

When I do this it does not encrypt the message. 当我这样做时,它不会加密邮件。 Using Fiddler I see the raw text of the message come across the wire and the service gives an error because it is expecting an encrypted message. 使用Fiddler,我看到消息的原始文本遍历整个网络,并且该服务给出了错误,因为它期望加密的消息。

Edit: Added comment about TransportWithMessageCrediential 编辑:添加了有关TransportWithMessageCrediential的注释

This is how we have solved this. 这就是我们解决这个问题的方式。 We are using a CustomBinding to set it all up. 我们正在使用CustomBinding进行设置。

This setups up the binding 这将设置绑定

private Binding GetBinding()
{
    var binding = new CustomBinding()
    // This could be configured per service
    MessageVersion messageVersion = MessageVersion.Soap12;

    TextMessageEncodingBindingElement messageEncodingElement = new TextMessageEncodingBindingElement(messageVersion, Encoding.UTF8);
    binding.Elements.Add(messageEncodingElement)
    if (/* Encryption is needed */)
    {
        SecurityBindingElement securityElement = securityElement = SecurityBindingElement.CreateAnonymousForCertificateBindingElement();
        securityElement.DefaultAlgorithmSuite = GetEncryptionAlgorithm(); // This will return which algorithm is desired
        securityElement.IncludeTimestamp = false; // This is because our services were returning an error when it was included
        binding.Elements.Add(securityElement);

    HttpsTransportBindingElement httpsTransportElement = new HttpsTransportBindingElement()
    if (/* If Windows Authentication is required */)
        httpsTransportElement.AuthenticationScheme = AuthenticationSchemes.Negotiate;
    binding.Elements.Add(httpsTransportElement)
    return binding;
}

Then to use the client 然后使用客户端

// By default WCF will check that the DnsName of the certificate matchs the DNS name of the endpoint we need to override this.
// We did want want to require an appliction to use the same cert that is for SSL as for message encryption
EndpointIdentity endpointIdentity = null;
if (endpoint.EncryptionCertificate != null)
    endpointIdentity = EndpointIdentity.CreateDnsIdentity(endpoint.EncryptionCertificate.GetCertificate().GetNameInfo(X509NameType.DnsName, false));
else
    endpointIdentity = EndpointIdentity.CreateDnsIdentity(endpoint.Address);


AddressHeader[] header = null;
using (var client = new portTypeClient(binding, new EndpointAddress(new Uri(address), endpointIdentity, header)))
{
    if (/* Encryption is needed */)
    {
        var certificate = LoadX509Certificate();
        client.ClientCredentials.ServiceCertificate.DefaultCertificate = certificate;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM