"基础连接已关闭:发送时发生意外错误." 使用SSL证书

Arv*_*wal 102 connection ssl

问题:我得到这个异常"的基础连接已关闭:意外错误发生在一个发送"我的日志,它是在随机时间打破了我们的OEM集成与我们的电子邮件营销系统从不同[1小时 - 4小时]

我的网站托管在带有IIS 7.5.7600的Windows Server 2008 R2上.该网站拥有大量的OEM组件和全面的仪表板.除了我们在仪表板中用作iframe解决方案的电子邮件营销组件之外,网站的所有其他元素都可以正常工作.它的工作方式是,我发送一个httpWebRequestobject与所有凭据,我得到一个网址,我把它放在一个iframe,它的工作原理.但它仅适用于一段时间[1 HOUR - 4小时],然后我得到下面的异常"的基础连接已关闭:意外错误发生在一个发送"即使系统尝试从HttpWebRequest的它获取URL失败,同样的例外.使其再次工作的唯一方法是回收应用程序池或在web.config中编辑任何内容.我真的很精疲力尽所有我能想到的选择.

选择尝试了

明确添加, keep-alive = false

keep-alive = true

增加时间: <httpRuntime maxRequestLength="2097151" executionTimeout="9999999" enable="true" requestValidationMode="2.0" />

我已将此页面上传到非SSL网站,以检查我们的生产服务器上的SSL证书是否正在建立连接以放弃一些方法.

非常感谢任何解决方向.

代码:

Public Function CreateHttpRequestJson(ByVal url) As String
    Try
        Dim result As String = String.Empty
        Dim httpWebRequest = DirectCast(WebRequest.Create("https://api.xxxxxxxxxxx.com/api/v3/externalsession.json"), HttpWebRequest)
        httpWebRequest.ContentType = "text/json"
        httpWebRequest.Method = "PUT"
        httpWebRequest.ContentType = "application/x-www-form-urlencoded"
        httpWebRequest.KeepAlive = False
        'ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3

        'TODO change the integratorID to the serviceproviders account Id, useremail 
        Using streamWriter = New StreamWriter(httpWebRequest.GetRequestStream())
            Dim json As String = New JavaScriptSerializer().Serialize(New With { _
            Key .Email = useremail, _
            Key .Chrome = "None", _
            Key .Url = url, _
            Key .IntegratorID = userIntegratorID, _
            Key .ClientID = clientIdGlobal _
            })

            'TODO move it to the web.config, Following API Key is holonis accounts API Key
            SetBasicAuthHeader(httpWebRequest, holonisApiKey, "")
            streamWriter.Write(json)
            streamWriter.Flush()
            streamWriter.Close()

            Dim httpResponse = DirectCast(httpWebRequest.GetResponse(), HttpWebResponse)
            Using streamReader = New StreamReader(httpResponse.GetResponseStream())
                result = streamReader.ReadToEnd()
                result = result.Split(New [Char]() {":"})(2)
                result = "https:" & result.Substring(0, result.Length - 2)
            End Using
        End Using
        Me.midFrame.Attributes("src") = result
    Catch ex As Exception
        objLog.WriteLog("Error:" & ex.Message)
        If (ex.Message.ToString().Contains("Invalid Email")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Email Taken")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Invalid Access Level")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Unsafe Password")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Invalid Password")) Then
            'TODO Show message on UI
        ElseIf (ex.Message.ToString().Contains("Empty Person Name")) Then
            'TODO Show message on UI
        End If
    End Try
End Function


Public Sub SetBasicAuthHeader(ByVal request As WebRequest, ByVal userName As [String], ByVal userPassword As [String])
    Dim authInfo As String = Convert.ToString(userName) & ":" & Convert.ToString(userPassword)
    authInfo = Convert.ToBase64String(Encoding.[Default].GetBytes(authInfo))
    request.Headers("Authorization") = "Basic " & authInfo
End Sub`
Run Code Online (Sandbox Code Playgroud)

Lan*_*aas 170

对我来说这是tls12:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您必须小心,因为此更改对您的AppDomain是全局的,并且将导致对任何不提供TLS 1.2的站点的调用失败(如果要传输的数据真正敏感,您可能更喜欢这种调用).要优先选择TLS 1.2但仍然允许1.1和1.0,你必须对它们进行OR运算:`ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;` (35认同)
  • 要在PowerShell中执行此操作,"二进制或"将它们组合在一起:`[Net.ServicePointManager] :: SecurityProtocol = [Net.SecurityProtocolType] :: Tls12 -bor [Net.SecurityProtocolType] :: Tls11 -bor [Net.SecurityProtocolType] :: Tls` (5认同)
  • 或者只是将它添加到已经存在的内容中... `System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;` (3认同)

小智 58

如果您遇到.Net 4.0并且目标站点使用的是TLS 1.2,则需要使用以下行. ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

来源:TLS 1.2和.NET支持:如何避免连接错误

  • 真棒!我只想补充一点,`(SecurityProtocolType)768`可以用于"Tls11"(即TLS 1.1). (5认同)
  • 这确实有帮助。它挽救了我的一天。我必须坚持使用.Net 2.0。 (2认同)

Arv*_*wal 20

下面的代码解决了这个问题

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Ssl3
Run Code Online (Sandbox Code Playgroud)

  • 但是,请注意,`ServicePointManager.SecurityProtocol`是一个静态对象,这意味着更改此值将影响所有子序列`WebRequest`或`WebClient`调用.如果您希望`ServicePointManager`具有不同的设置,您可以创建单独的`AppDomain`.有关详细信息,请参阅http://stackoverflow.com/questions/3791629/set-the-securityprotocol-ssl3-or-tls-on-the-net-httpwebrequest-per-request. (4认同)

abo*_*021 13

在我的情况下,我正在连接的网站已升级到TLS 1.2.因此,我必须在我的Web服务器上安装.net 4.5.2才能支持它.


小智 9

几天来我一直在遇到一个同样的问题,它的集成也只是“以前可以使用”。

出于纯粹的沮丧,我只是尝试

 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Ssl3;
Run Code Online (Sandbox Code Playgroud)

这为我解决了..即使集成严格只使用SSLv3。

我意识到,自Fiddler报告说存在“空TLS协商密码”之类的东西以来,这种情况就不存在了。

希望它能工作!


Guo*_*ang 8

转到web.config/App.config以验证您正在使用的.net运行时

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>
Run Code Online (Sandbox Code Playgroud)

这是解决方案:

  1. .NET 4.6及更高版本.您不需要执行任何其他工作来支持TLS 1.2,默认情况下它是受支持的.

  2. .NET 4.5.支持TLS 1.2,但它不是默认协议.您需要选择使用它.以下代码将使TLS 1.2成为默认值,请确保在连接到安全资源之前执行它:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12

  1. .NET 4.0.不支持TLS 1.2,但如果您在系统上安装了.NET 4.5(或更高版本),那么即使您的应用程序框架不支持TLS 1.2,您仍然可以选择使用TLS 1.2.唯一的问题是.NET 4.0中的SecurityProtocolType没有TLS1.2的条目,因此我们必须使用此枚举值的数字表示:

ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072;

  1. .NET 3.5或更低版本.不支持TLS 1.2(*)并且没有解决方法.将您的应用程序升级到更新版本的框架.

  • +1 - 你的答案的这一部分是关键**确保在连接到安全资源之前执行它:**。在使用“var request = (HttpWebRequest)WebRequest.Create(url);”创建请求后,我设置了“SecurityProtocol”。这意味着第一个请求总是失败,但后续请求都很好。将集合移动到创建“请求”对象之前对其进行排序。 (2认同)

Pat*_*ick 6

我发现这表明您部署代码的服务器安装了一个不支持TLS 1.1或TLS 1.2的旧.NET框架.修复步骤:

  1. 在生产服务器上安装最新的.NET Runtime(IIS和SQL)
  2. 在开发计算机上安装最新的.NET Developer Pack.
  3. 将Visual Studio项目中的"目标框架"设置更改为最新的.NET框架.

您可以从以下URL获取最新的.NET Developer Pack和Runtime:http://getdotnet.azurewebsites.net/target-dotnet-platforms.html


小智 6

我通过使用以下代码更新 web.config 找到了解决方案。

我的 .Net Framwork 设置为 4.0,在组织级别 TLS 协议更新后,我突然开始面临这个问题。所以我参考了上面“Guo Huang”的答案并更新了 targetFramework 并且它起作用了。

<system.web>
        <compilation debug="true" targetFramework="4.7.2" />
        <httpRuntime targetFramework="4.7.2"  maxRequestLength="102400" executionTimeout="3600"/>
</system.web>
Run Code Online (Sandbox Code Playgroud)


tom*_*dox 5

我们遇到了这个问题,访问我们 API 的网站收到 \xe2\x80\x9cThe底层连接已关闭:发送时发生意外错误。\xe2\x80\x9d 消息。

\n\n

他们的代码混合了 .NET 3.x 和 2.2,据我了解,这意味着他们正在使用 TLS 1.0。

\n\n

下面的答案可以通过启用 TLS 1.0、SSL 2 和 SSL3 来帮助您诊断问题,但要非常明确的是,您不希望长期这样做,因为所有这三个协议都被视为不安全,不应再启用用过的

\n\n

为了让 IIS 响应其 API 调用,我们必须在 IIS 服务器上添加注册表设置以显式启用 TLS 版本 - 注意:进行这些更改后,您必须重新启动 Windows 服务器(不仅仅是 IIS 服务) :

\n\n
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS\n1.0\\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001\n\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS\n1.0\\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001\n\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS\n1.1\\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001\n\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS\n1.1\\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001\n\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS\n1.2\\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001\n\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\TLS\n1.2\\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果这不起作用,您还可以尝试添加 SSL 2.0 条目:

\n\n
[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\SSL 2.0\\Client]\n"DisabledByDefault"=dword:00000000\n"Enabled"=dword:00000001\n\n[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\SSL 2.0\\Server]\n"DisabledByDefault"=dword:00000000\n"Enabled"=dword:00000001\n
Run Code Online (Sandbox Code Playgroud)\n\n

需要明确的是,这不是一个好的解决方案,正确的解决方案是让调用者使用 TLS 1.2,但上述内容可以帮助诊断这就是问题所在。

\n\n

您可以使用此 powershell 脚本加速添加这些注册表项:

\n\n
$ProtocolList       = @("SSL 2.0","SSL 3.0","TLS 1.0", "TLS 1.1", "TLS 1.2")\n$ProtocolSubKeyList = @("Client", "Server")\n$DisabledByDefault = "DisabledByDefault"\n$Enabled = "Enabled"\n$registryPath = "HKLM:\\\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders\\SCHANNEL\\Protocols\\"\n\nforeach($Protocol in $ProtocolList)\n{\n    Write-Host " In 1st For loop"\n        foreach($key in $ProtocolSubKeyList)\n        {         \n            $currentRegPath = $registryPath + $Protocol + "\\" + $key\n            Write-Host " Current Registry Path $currentRegPath"\n            if(!(Test-Path $currentRegPath))\n            {\n                Write-Host "creating the registry"\n                    New-Item -Path $currentRegPath -Force | out-Null             \n            }\n            Write-Host "Adding protocol"\n                New-ItemProperty -Path $currentRegPath -Name $DisabledByDefault -Value "0" -PropertyType DWORD -Force | Out-Null\n                New-ItemProperty -Path $currentRegPath -Name $Enabled -Value "1" -PropertyType DWORD -Force | Out-Null    \n    }\n}\n\xe2\x80\xaf\nExit 0\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是 Microsoft 帮助页面中Set up TLS for VMM脚本的修改版本。这篇basics.net 文章最初让我想到查看这些设置。

\n


小智 5

只需添加:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

  • 这个答案对以前的答案也没有任何补充。 (4认同)
  • 请在您的回答中提供解释。 (2认同)