使用SetCertificatePolicy()建立安全Web服务的信任关系

时间:2011-12-21 11:05:34

标签: c# web-services ssl ssl-certificate

我在C#中编写了一个.NET应用程序,它接触了一些Web服务。当我在非安全URL上引用Web服务时,一切正常;但是当我在安全的HTTPS URL上引用相同的Web服务时,我收到一条例外消息“无法为SSL / TLS安全通道建立信任关系”。

我在这个网页http://www.codemeit.com/wcf/wcf-could-not-establish-trust-relationship-for-the-ssltls-secure-channel-with-authority.html被指出。并将代码添加到我的应用程序中。这解决了这个问题,我现在可以按预期使用安全的Web服务。

我注意到上面的代码片段“不打算在生产环境中使用”,它目前信任任何证书。为了使生产环境更安全,我应该检查它是否有我们自己的证书?我应该如何检查,RemoteCertificateValidate()方法中的'cert'参数中包含大量信息,因此我不确定应该检查的方式或内容。

TIA

1 个答案:

答案 0 :(得分:0)

当客户端建立安全SSL连接时,服务器使用的证书很可能存在身份验证问题。根据我的经验,这主要是由服务器返回的证书未由受信任的根权限签名或链中的一个或多个证书无效(例如,它们已过期或用于除您之外的域)连接到)。

为了帮助确定问题,您可以尝试浏览服务端点URL并查看浏览器是否报告任何问题。如果服务器证书无效,现代浏览器会发出警告,有时会告诉您原因。如果您使用Chrome并且证书存在问题,您会在地址栏左侧的挂锁图标(或多功能框)中看到红叉。如果您点击挂锁,Chrome会告诉您它为什么不喜欢该证书。

至于您找到的代码段,这是如何在.Net中实现服务器证书验证作为客户端的示例。但是,即使服务器证书存在问题,示例本身也绝不会拒绝与服务器的连接,因此关于不在生产中使用代码的注释。在测试场景之外,您永远不希望与由于证书错误而无法信任的身份的服务器进行通信。要提供“生产”实现,您必须检查“error”参数的值以查看证书是否存在任何问题,并且只有在没有问题时才返回true。

using System;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            // Attach my certificate validation delegate.
            ServicePointManager.ServerCertificateValidationCallback += ValidateRemoteCertificate;

            System.Net.HttpWebRequest request = WebRequest.CreateHttp("https://www.google.com");
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
        }

        private static bool ValidateRemoteCertificate(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
        {
            if (error == SslPolicyErrors.None)
            {
                return true;
            }

            return false;
        }
    }
}

在这个例子中,如果error的值等于SslPolicyErrors.None,我只从我的ServerCertificateValidationCallback委托返回true,否则我返回false,这会产生异常。为了使这个示例工作,我使用Fiddler代理请求并将不受信任的证书返回给我的客户端代码。如果您在正常情况下导航至https://www.google.com,则会看到任何证书错误,因为Google会玩得很好!!

带有证书的PKI可以是一个可以使用的粗糙域。在文档Wikipedia has a good article on PKI方面,它涵盖了如何使用受信任的权限来签署SSL中使用的证书,以便客户端可以信任他们正在通信的服务器的身份用。