C# 调试失败的HTTPS WebRequest

C# 调试失败的HTTPS WebRequest,c#,.net,https,httpwebrequest,x509certificate,C#,.net,Https,Httpwebrequest,X509certificate,我正在编写一个小程序,它将使用HTTPS和HttpWebRequest类向服务器发出GET请求。服务器(显然)有一个服务器证书。它还希望客户端提供一个证书 但是,在发出请求时,我收到一个System.Net.WebException,指出无法建立安全的TLS/SSL连接。我很快发现服务器的证书无效。假设这就是导致异常的原因,我尝试使用以下代码接受无效证书(很遗憾,更新证书不是选项): ServicePointManager.ServerCertificateValidationCallback

我正在编写一个小程序,它将使用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!
一些想法:

  • TLS定义了一些错误代码和警报。SSL/TLS库通常在引发异常时提供此代码。也许你能在服务器日志中找到这些信息

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

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


  • 给它涂上点痕迹!在调试这些东西时,跟踪是您最好的朋友。我曾经有一个客户端无法连接到支持SSL的服务。通过跟踪,我发现有人将系统时钟移过了我们的证书到期日期。但我离题了

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

    有一本杜加普拉萨德·戈尔蒂(Durgaprasad Gorti)写的老(2005)书,你应该去看看。它将准确地向您显示要添加的源,并且在其中,他还使用自定义验证回调显示了一些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>
    
    
    

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

    我同意上面Markus的解决方案。我曾经遇到过类似的问题,我发现最好的办法是在调试器下获取该异常

    如果您可以在本地运行构建并在调试器中查看该异常,那么在深入了解问题的实质之前,您必须深入几个级别

    在我想到的这个例子中,我必须先查看4到5个内部异常,然后才能得到明确告诉我问题所在的消息

    我发现在.Net中的许多情况下通常都是这样的-您将得到一个异常,该异常包含一条非常通用的错误消息,您需要将几个“innerException”级别降低,然后才能讨论问题的实质


    希望这有帮助。

    FWIW,您可以在使用应用程序时尝试运行Fiddler(www.fiddler2.com)。Fiddler倾向于在这样的情况下显示更多描述性错误消息。Jcs:第3点很可能是我的问题(我还没有机会看到跟踪告诉我什么)。我该如何解决这个问题?如何添加SSL堆栈将检查的根证书?客户端身份验证CA的配置方式肯定取决于服务器应用程序,或者至少取决于处理SSL/TLS的模块。