调试失败的 HTTPS WebRequest
Posted
技术标签:
【中文标题】调试失败的 HTTPS WebRequest【英文标题】:Debugging failing HTTPS WebRequest 【发布时间】:2011-08-24 02:01:15 【问题描述】:我正在编写一个小程序,它将使用 HTTPS 和 HttpWebRequest 类向服务器发出 GET 请求。服务器(显然)具有服务器证书。它还希望客户端提供证书。
但是,在发出请求时,我收到 System.Net.WebException,指出无法建立安全的 TLS/SSL 连接。我很快发现服务器的证书无效。假设这是导致异常的原因,我尝试使用以下代码接受无效证书(不幸的是,更新证书不是一种选择):
ServicePointManager.ServerCertificateValidationCallback += delegate
return true;
;
然而,这并没有解决问题。
由于异常没有提供任何细节,因此很难确定是什么原因造成的。我尝试覆盖无效的服务器证书是否不起作用?我提供的客户端证书是否不受服务器信任?我没有以正确的方式加载客户端证书吗?
我很想知道如何调试这类问题的提示。很遗憾,我无权访问服务器或其日志。
下面是代码的重要部分:
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!
【问题讨论】:
FWIW,您可以尝试在使用您的应用程序时运行 Fiddler (www.fiddler2.com)。在这种情况下,Fiddler 往往会显示更具描述性的错误消息。 【参考方案1】:对其进行一些跟踪!在调试这些东西时,跟踪是你最好的朋友。我曾经有一个客户端无法连接到我们启用 SSL 的服务。使用跟踪我发现有人将系统时钟移到了我们的证书到期日期之后。但我离题了。
启用所有适用的跟踪源并查看日志中是否出现有趣的内容。
Durgaprasad Gorti 有一个旧的(2005 年)但 excellent post,你应该看看。它会准确地向您显示要添加的源,并且在其中他还使用自定义验证回调显示了一些 SSL 跟踪。
来自同一篇博文的 app.config 示例:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net">
<listeners>
<add name="MyTraceFile"/>
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="MyTraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="System.Net.trace.log"
/>
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
</switches>
</system.diagnostics>
</configuration>
希望这将为您提供更多数据。
【讨论】:
【参考方案2】:一些想法:
TLS 定义了一些错误代码和警报。 SSL/TLS 库通常在引发异常时提供此代码。也许你能在服务器日志中找到这些信息。
服务器发送其证书链时可能缺少一些证书。例如,如果服务器仅发送其证书,则客户端可能无法将此证书附加到根证书(如果有一些中间 CA 证书)。
如果客户端希望使用证书进行身份验证,则服务器应该发送接受的根证书的名称。我的前一点在这里也有效,如果缺少某些中间证书,则无法在其证书和服务器发送的根之间建立链。客户端找不到合适的证书(因为私钥不可用)是另一个可能的问题。
【讨论】:
Jcs:第 3 点很可能是我的问题(我还没有机会看到痕迹告诉我什么)。我将如何解决这个问题?如何添加 SSL 堆栈将检查的根证书? 客户端认证 CA 的配置方式肯定取决于服务器应用程序,或者至少取决于处理 SSL/TLS 的模块。【参考方案3】:我同意上述 Markus 的解决方案。我曾经遇到过类似的问题,我发现最好的办法是在调试器下获取该异常。
如果您可以在本地运行构建并在调试器中查看该异常,那么您必须深入了解问题的真正实质。
在我正在考虑的情况下,我必须查看 4 或 5 个 innerExceptions,然后才能看到具体告诉我出了什么问题的消息。
我发现这在 .Net 中的许多情况下通常是正确的——你会得到一个带有非常通用的错误消息的异常,并且你需要在深入了解之前降低几个“innerException”级别问题。
希望这会有所帮助。
【讨论】:
以上是关于调试失败的 HTTPS WebRequest的主要内容,如果未能解决你的问题,请参考以下文章