Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF传输安全,匿名访问的消息加密_C#_Asp.net_Wcf - Fatal编程技术网

C# WCF传输安全,匿名访问的消息加密

C# WCF传输安全,匿名访问的消息加密,c#,asp.net,wcf,C#,Asp.net,Wcf,我正在尝试设置一个WCF客户端,以便与服务对话。连接需要是https(传输安全),我们需要使用公钥进行消息加密。我们没有要显示的客户端证书 var binding = new WSHttpBinding(); binding.Security.Mode = SecurityMode.Transport; // This is failing because the private key for client authentication is not being set // binding.

我正在尝试设置一个WCF客户端,以便与服务对话。连接需要是https(传输安全),我们需要使用公钥进行消息加密。我们没有要显示的客户端证书

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;
然后设置我正在做的公钥

client.ClientCredentials.ServiceCertificate.DefaultCertificate = certificate;
其中,certificate是仅具有公钥的X509Certificate2对象

当我这样做时,它不会加密消息。使用Fiddler,我看到消息的原始文本通过网络传输,服务给出了一个错误,因为它需要加密消息


编辑:添加了关于TransportWithMessageCrediential的评论这就是我们解决这个问题的方法。我们正在使用CustomBinding进行设置

这将设置绑定

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;
}
然后使用客户端

// 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;
    }
}

通常,对大多数人来说,数据加密一次就足够了。你真的想要TLS和消息安全吗?是的,因为它保护了中间人的攻击。我们正在发送PII,并且需要对消息进行加密。对于WSHttpBinding,我认为您只能将安全性设置为
Transport
message
。你不能两者兼得。您似乎还混淆了加密和凭据。凭据不会加密邮件。他们告诉服务器呼叫者是谁。至于Fiddler能够看到您的消息,您是否让它安装了可信证书?因为如果你这样做,那么它可以做一个中间人的“攻击”。为了防止出现这种情况,可以执行“证书固定”,即检查服务器的证书是否符合预期。WSHttpBinding允许这两种方法()。小提琴确实安装了根CA证书,它允许我解密和查看HTTPS消息,但它仍然显示给我,如果它被加密使用消息加密(因此两者都需要)。“是的,因为它防止中间人攻击”。TLS也应该能够做到这一点,因为它需要一个客户端必须信任的证书。中间人只有在客户信任“中间人”证书的情况下才会成功。只有在有权访问客户证书存储的某些组织进行https检查时,才会发生这种情况。