调试失败的 HTTPS WebRequest
我正在编写一个小程序,它将使用 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!
I'm writing a small program which will make a GET request to a server using HTTPS and the HttpWebRequest class. The server (obviously) has a server certificate. It also expects the client to provide a certificate.
When making the request, however, I get a System.Net.WebException stating that it wasn't possible to establish a secure TLS/SSL connection. I quickly discovered that the server's certificate wasn't valid. Assuming this was what was causing the exception, I tried to accept the invalid certificate (updating the certificate is, unfortunately, not an option) using the code below:
ServicePointManager.ServerCertificateValidationCallback += delegate {
return true;
};
That didn't solve the problem, however.
Since the exception doesn't give any detail, it's hard to actually determine what is causing it. Is my attempt to override the invalid server certificate not working? Is the client certificate I'm providing not trusted by the server? Am I not loading the client certificate in the proper manner?
I'd love tips on how to debug this sort of problem. I do not have access to the server or its logs, unfortunately.
Below is the important parts of the code:
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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在上面画一些描边!调试这些东西时,跟踪是你最好的朋友。我曾经有一个客户端无法连接到我们启用 SSL 的服务。通过跟踪,我发现有人将系统时钟移到了我们的证书到期日期之后。但我离题了。
启用所有适用的跟踪源并查看日志中是否显示一些有趣的内容。
有一个旧的(2005)但是Durgaprasad Gorti 的优秀帖子,您应该看看。它将准确地向您显示要添加的源,并且在其中还使用自定义验证回调显示了一些 SSL 跟踪。
来自同一博客文章的示例 app.config:
希望这能为您提供更多数据。
Slap some tracing on it! Traces are your best friend when debugging these things. I once had one client which couldn't connect to our SSL-enabled service. Using tracing I found that someone had moved the system clock past our certificate expiry date. But I digress.
Enable all applicable trace sources and see if something interesting show up in the logs.
There's an old (2005) but excellent post by Durgaprasad Gorti that you should check out. It'll show you exactly what sources to add and in it he also shows some SSL traces using a custom validation callback.
Example app.config from the very same blog post:
Hopefully that'll provide you with some more data.
一些想法:
TLS 定义了一些错误代码和警报。 SSL/TLS 库通常在引发异常时提供此代码。也许您可以在服务器日志中找到此信息。
服务器发送其证书链时,可能缺少一些证书。例如,如果服务器仅发送其证书,并且存在某些中间 CA 证书,则客户端可能无法将此证书附加到根证书。
如果客户端需要使用证书进行身份验证,服务器应该发送接受的根证书的名称。我之前的观点在这里也有效,如果缺少某些中间证书,则无法在其证书和服务器发送的根之间建立链。客户端找不到合适的证书(因为私钥不可用)是另一个可能的问题。
Some thoughts:
TLS defines some error codes and alerts. SSL/TLS libraries often provides this code when an exception is thrown. Maybe could you find this information in the server log.
Maybe there is some missing certificates when the server sends its certificate chain. For instance if the server sends only its certificate the client may not be able to attach this certificate to a root certificate if there is some intermediate CA certificate.
If the client is expected to use a certificate for authentication the server is supposed to send the names of the accepted root certificates. My previous point is also valid here, if some intermediate certificates are missing the cannot build a chain between its certificate and a root sent by the server. The client does not find a suitable certificate (because a private key is not available) is another possible issue.
我同意上面马库斯的解决方案。我曾经遇到过类似的问题,我发现最好的办法是在调试器下获取该异常。
如果您可以在本地运行构建并在调试器中查看该异常,那么您必须深入几个级别才能了解问题的实质。
在我想到的情况下,我必须先查看 4 或 5 个内部异常,然后才能看到具体告诉我出了什么问题的消息。
我发现在 .Net 中的许多情况下,这往往是正确的 - 您将得到一个异常,其中包含非常通用的错误消息,并且您需要深入了解几个“innerException”级别,然后才能解决问题的实质。
希望这有帮助。
I agree with Markus's solution above. I once had a similar issue, and I found that the best thing to do is get that exception under a debugger.
If you can run a build locally and look at that exception in the debugger, you have to drill down several levels before you get to the real meat of the issue.
In the case I'm thinking of, I had to look through 4 or 5 innerExceptions before I got to the message that told me specifically what was wrong.
I found that this tends to be true in many cases in .Net generally - you will get an exception which has a very generic error message, and you need to dive several "innerException" levels down before you get to the meat of the issue.
Hope this helps.