HttpWebrequest失败,内部异常验证失败,因为远程方已关闭传输流

时间:2013-10-28 16:14:56

标签: c# asp.net ssl-certificate vmware system.net.webexception

使用C#,。Net 4.5,我试图通过远程服务器上的HttpWebRequest发送Web请求。请参阅下面的代码。 我尝试了一些论坛建议的大多数解决方案,但我总是遇到同样的错误。请参阅下面的堆栈跟踪。 调用request.GetReponse()方法时抛出错误。

其他信息,基本上,我正在尝试调用安装在远程服务器上的vmware vCenter组件的reloadSslCertificate功能。目前,该错误仅发生在vCenter 5.5上。它在5.1及以下版本中运行良好。

        var uri = String.Format("https://{0}/some_url", serverName);
        var request = (HttpWebRequest)WebRequest.Create(uri);
        request.KeepAlive = true;
        request.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
        request.Headers.Set(HttpRequestHeader.AcceptLanguage, "en-US,en;q=0.8");
        request.Credentials = credential;
        request.CookieContainer = cookieContainer;


        var response = request.GetResponse();
  

异常:System.Net.WebException:底层连接是   已关闭:发送时发生意外错误。 --->   System.IO.IOException:身份验证失败,因为远程方   关闭了运输流。在   System.Net.Security.SslState.StartReadFrame(Byte []缓冲区,Int32   readBytes,AsyncProtocolRequest asyncRequest)at   System.Net.Security.SslState.StartReceiveBlob(Byte []缓冲区,   AsyncProtocolRequest asyncRequest)at   System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken   消息,AsyncProtocolRequest asyncRequest)at   System.Net.Security.SslState.StartSendBlob(Byte [] incoming,Int32   count,AsyncProtocolRequest asyncRequest)at   System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst,   Byte [] buffer,AsyncProtocolRequest asyncRequest)at   System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult   lazyResult)在System.Net.TlsStream.CallProcessAuthentication(Object   国家)   System.Threading.ExecutionContext.RunInternal(执行上下文   executionContext,ContextCallback回调,对象状态,布尔值   preserveSyncCtx)at   System.Threading.ExecutionContext.Run(执行上下文   executionContext,ContextCallback回调,对象状态,布尔值   preserveSyncCtx)at   System.Threading.ExecutionContext.Run(执行上下文   executionContext,ContextCallback回调,对象状态)at   System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)at   System.Net.TlsStream.Write(Byte []缓冲区,Int32偏移量,Int32大小)at   System.Net.PooledStream.Write(Byte []缓冲区,Int32偏移量,Int32大小)   在System.Net.ConnectStream.WriteHeaders(布尔异步)---结束   内部异常堆栈跟踪--- at   System.Net.HttpWebRequest.GetResponse()

提前致谢。

3 个答案:

答案 0 :(得分:23)

我只想分享一下这个问题已经解决了。

我刚刚在发出网络请求之前修改了我设置安全协议的代码部分。

自:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

要:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls;

事实证明,vCenter 5.5在其配置中使用TLS作为其SSL协议。我希望人们在遇到同样的问题时可能会觉得有用。

答案 1 :(得分:14)

我们遇到了同样的例外。在我们的案例中,答案与@Dennis Laping的回答非常相似。另一个团队设置了我们试图在Rancher负载均衡器中命中的服务,默认情况下不允许使用TLS 1.0或SSL3。恰好在.NET中SecurityProtocol(未设置)的当前默认值仅允许TLS 1.0或SSL3。

一旦我们将SecurityProtocol设置如下,一切正常:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

所有这些,SecurityProtocol的文档指出:

  

您的代码永远不会隐含地依赖于使用特定的保护级别,或者假设默认情况下使用给定的安全级别。如果您的应用程序依赖于特定安全级别的使用,则必须明确指定该级别,然后检查以确保它在已建立的连接上实际使用。此外,面对支持哪些协议的更改,您的代码应该设计为健壮的,因为这些更改通常很少提前通知,以便缓解新出现的威胁。

我们将重新评估我们的协议情况的最佳解决方案,但是现在我希望这可以帮助其他人。

答案 2 :(得分:1)

看到此链接,它对我有用: How to do HTTPS with TcpClient just like HttpWebRequest does?

Dim trust_all_certificates As New CertificateOverride
ServicePointManager.ServerCertificateValidationCallback = AddressOf trust_all_certificates.RemoteCertificateValidationCallback
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3

Public Class CertificateOverride

    Public Function RemoteCertificateValidationCallback(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean

        'CertEXPIRED = 2148204801
        'CertVALIDITYPERIODNESTING = 2148204802
        'CertPATHLENCONST = 2148204804
        'CertROLE = 2148204803
        'CertCRITICAL = 2148204805
        'CertPURPOSE = 2148204806
        'CertISSUERCHAINING = 2148204807
        'CertMALFORMED = 2148204808
        'CertUNTRUSTEDROOT = 2148204809
        'CertCHAINING = 2148204810
        'CertREVOKED = 2148204812
        'CertUNTRUSTEDTESTROOT = 2148204813
        'CertREVOCATION_FAILURE = 2148204814
        'CertCN_NO_MATCH = 2148204815
        'CertWRONG_USAGE = 2148204816
        'CertUNTRUSTEDCA = 2148204818

        Return True

    End Function

End Class

P.S。

我之前插入了这行代码,以确保接受服务器端的证书:ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3