使用自签名证书从Winforms客户端对SSL安全WCF服务进行身份验证

本文关键字:WCF 安全 SSL 服务 身份验证 客户端 证书 Winforms | 更新日期: 2023-09-27 18:16:02

我正试图使用IIS生成的自签名证书从WinForms客户端连接到WCF服务,但无论我做什么,我都会得到"无法与权威机构建立SSL/TLS安全通道的信任关系…"。

我的Web.config如下所示:

 ...
<binding name="BasicHttpBinding_TransportCertificate">
      <security mode="Transport">
        <transport clientCredentialType="Certificate" />
      </security>
</binding>
...
<endpoint address="transportCertificate" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_TransportCertificate"
        name="TransportCertificateEndpoint" contract="MyService"/>

我的客户端代码如下:

private void Ping(string endpointAddress)
{
    var binding = new BasicHttpContextBinding();
    binding.Security.Mode = BasicHttpSecurityMode.Transport;
    binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
    var service = new CMServiceReference.CMServiceClient(binding,
        new EndpointAddress(string.Format("{0}/{1}", endpointAddress, "transportCertificate")));
    service.ClientCredentials.ClientCertificate.SetCertificate(
                        StoreLocation.CurrentUser, 
                        StoreName.My,
                        X509FindType.FindBySubjectName, 
                        "server.domain.com");
    service.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust;
    service.Ping();
}

设置已经安装在客户端机器上的证书似乎工作得很好,但在调用服务时,我仍然会遇到同样的错误。Ping((。我曾尝试过CertificateValidationMode选项,但这些选项似乎都没有任何区别。

有什么明显的东西我遗漏了吗?


解决问题后在下面进行编辑

事实证明,自签名证书一直在客户端的错误存储中。它需要在本地计算机/受信任的根证书颁发机构中。之后,它可以在WCF属性上不指定"证书"的情况下正常工作。

在把证书放在正确的位置后,我只是简单地更新了我的Web.config,如下所示:

...
<binding name="BasicHttpBinding_TransportCertificate">
      <security mode="Transport">
        <transport clientCredentialType="None" />
      </security>
</binding>
...
<endpoint address="transportCertificate" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_TransportCertificate"
        name="TransportCertificateEndpoint" contract="MyService"/>

我的客户端代码如下:

private void Ping(string endpointAddress)
{
    var binding = new BasicHttpContextBinding();
    binding.Security.Mode = BasicHttpSecurityMode.Transport;
    var service = new CMServiceReference.CMServiceClient(binding,
        new EndpointAddress(string.Format("{0}/{1}", endpointAddress, "transportCertificate")));
    service.Ping();
}

使用自签名证书从Winforms客户端对SSL安全WCF服务进行身份验证

我认为该错误发生在涉及客户端证书之前,即错误是您的客户端应用程序不信任服务器,而不是服务器不信任您的客户端证书。

如果IIS证书是自签名的,则需要将该证书作为受信任的根证书安装在本地计算机上。

或者,如果你所做的只是为了测试,你可以按照这个答案中的建议去做:C#忽略证书错误?

这将忽略客户端与服务器之间的任何信任问题。

service.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.PeerTrust;

根据MSDN,X509CertificateValidationMode.PeerTrust意味着如果证书在受信任的人存储中,则证书是有效的,但StoreName.My在上面的函数中意味着从个人证书存储中查找证书,我认为这就是问题的原因。

如果证书在StoreName.My中,则可以删除该行。