调试失败的HTTPS WebRequest

我正在编写一个小程序,它将使用HTTPS和HttpWebRequest类向服务器发出GET请求。 服务器(显然)有一个服务器证书。 它还希望客户提供证书。

但是,在发出请求时,我收到一个System.Net.WebException,指出无法建立安全的TLS / SSL连接。 我很快发现服务器的证书无效。 假设这是造成exception的原因,我试图接受无效证书(遗憾的是,更新证书不是一个选项),使用下面的代码:

ServicePointManager.ServerCertificateValidationCallback += delegate { return true; }; 

然而,这并没有解决问题。

由于exception没有给出任何细节,因此很难确定导致它的原因。 我尝试覆盖无效的服务器证书是否无效? 我提供的客户端证书是否不受服务器信任? 我没有以正确的方式加载客户端证书吗?

我喜欢有关如何调试此类问题的提示。 遗憾的是,我无法访问服务器或其日志。

以下是代码的重要部分:

 ServicePointManager.ServerCertificateValidationCallback += delegate { return true; }; HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url); // url is an HTTPS URL. X509Certificate clientCert = new X509Certificate("certificate.crt", "password"); req.ClientCertificates.Add(clientCert); WebResponse resp = req.GetResponse(); // This fails! 

对它进行一些追踪! 在调试这些东西时,Traces是你最好的朋友。 我曾经有一个客户端无法连接到我们启用SSL的服务。 使用跟踪我发现有人将系统时钟移到我们的证书到期日期之后。 但我离题了。

启用所有适用的跟踪源,并查看日志中是否显示有趣的内容。

Durgaprasad Gorti有一篇古老的(2005年)但很棒的post ,你应该看看。 它将向您显示要添加的内容,并在其中使用自定义validation回调显示一些SSL跟踪。

来自同一篇博文的示例app.config:

                    

希望这能为您提供更多数据。

一些想法:

  1. TLS定义了一些错误代码和警报。 SSL / TLS库通常在抛出exception时提供此代码。 也许您可以在服务器日志中找到此信息。

  2. 当服务器发送其证书链时,可能会丢失一些证书。 例如,如果服务器仅发送其证书,则如果存在某个中间CA证书,则客户端可能无法将此证书附加到根证书。

  3. 如果希望客户端使用证书进行身份validation,则服务器应该发送已接受的根证书的名称。 我之前的观点在这里也是有效的,如果缺少某些中间证书,则无法在其证书与服务器发送的根之间建立链。 客户端找不到合适的证书(因为私钥不可用)是另一个可能的问题。

我同意Markus的解决方案。 我曾经有类似的问题,我发现最好的办法是在调试器下获得该exception。

如果您可以在本地运行构建并在调试器中查看该exception,则必须深入了解几个级别才能找到问题的真正含义。

在我想到的情况下,在得到告诉我特别是错误的消息之前,我必须查看4或5个innerExceptions。

我发现在.Net的许多情况下这通常都是正确的 – 你会得到一个exception,它有一个非常一般的错误信息,你需要在问题解决之前潜入几个“innerException”级别。

希望这可以帮助。