HttpWebrequest失败,内部exceptionvalidation失败,因为远程方已关闭传输流

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

其他信息,基本上,我正在尝试调用安装在远程服务器上的vmware的vCenter组件的reloadSslCertificatefunction。 目前,该错误仅发生在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(); 

exception:System.Net.WebException:基础连接已关闭:发送时发生意外错误。 —> System.IO.IOException:身份validation失败,因为远程方已关闭传输流。 System.Net.Security.SslState.Ss上的System.Net.Security.SslState.StartReadFrame(Byte []缓冲区,Int32 readBytes,AsyncProtocolRequest asyncRequest)中的System.Net.Security.SslState.StartReceiveBlob(Byte []缓冲区,AsyncProtocolRequest asyncRequest)。 System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst,Byte [] buffer,AsyncProtocolRequest)上的System.Net.Security.SslState.StartSendBlob(Byte []传入,Int32计数,AsyncProtocolRequest asyncRequest)中的CheckCompletionBeforeNextReceive(ProtocolToken消息,AsyncProtocolRequest asyncRequest) asyncRequest)在System.Net.Se.SlsStream.CallProcessAuthentication(对象状态)的System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)处于System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext,ContextCallback callback,Object state,Boolean preserveSyncCtx)at at System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态,布尔保留) ncCtx)System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态),位于System.Net.TlsStream.Write的System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult结果)(Byte []缓冲区,Int32偏移量,Int32 System.Net.ConnectStream.WriteHeaders(布尔异步)处的System.Net.PooledStream.Write(Byte []缓冲区,Int32偏移量,Int32大小)—内部exception堆栈跟踪结束—在System.Net上.HttpWebRequest.GetResponse()

提前致谢。

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

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

从:

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3; 

至:

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

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

我们遇到了同样的例外。 在我们的案例中,答案与@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的文档指出:

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

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

看到这个链接,它对我有用 : 如何像HttpWebRequest一样用TcpClient做HTTPS?

 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 

PS

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