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

时间:2014-03-25 07:27:44

标签: ssl connection

问题:我得到了这个例外"基本连接已经关闭:发生意外的错误"在我的日志中,随着时间的推移,它突破了我们与我们的电子邮件营销系统的OEM集成[1小时-4小时]

我的网站托管在带有IIS 7.5.7600的Windows Server 2008 R2上。该网站拥有大量的OEM组件和全面的仪表板。除了我们在仪表板中用作iframe解决方案的电子邮件营销组件之外,网站的所有其他元素都可以正常工作。它的工作方式是,我发送一个httpWebRequestobject与所有凭据,我得到一个网址,我把它放在一个iframe,它的工作原理。但它只能工作一段时间[1小时-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`

14 个答案:

答案 0 :(得分:147)

对我而言,这是tls12:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

答案 1 :(得分:47)

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

来源:TLS 1.2 and .NET Support: How to Avoid Connection Errors

答案 2 :(得分:17)

以下代码解决了问题

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls Or SecurityProtocolType.Ssl3

答案 3 :(得分:11)

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

答案 4 :(得分:8)

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

  <startup>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
  </startup>

这是解决方案:

  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(*),并且没有解决方法。将您的应用程序升级到该框架的最新版本。

答案 5 :(得分:6)

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

  1. 在生产服务器上安装最新的.NET 运行时(IIS&amp; SQL)
  2. 在开发计算机上安装最新的.NET 开发人员包
  3. 将Visual Studio项目中的“目标框架”设置更改为最新的.NET框架。
  4. 您可以从以下网址获取最新的.NET Developer Pack和Runtime:http://getdotnet.azurewebsites.net/target-dotnet-platforms.html

答案 6 :(得分:5)

我几天来一直遇到同样的问题,其整合也只是“过去曾经工作过”。

出于纯粹的抑郁症,我只是尝试了

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

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

我开始意识到,自从Fiddler报道说有一个“空的TLS协商密码”之类的东西以后就会出现问题。

希望它有效!

答案 7 :(得分:3)

我们遇到了一个问题,正在访问我们的API的网站收到“关闭了基础连接:发送中发生意外错误。”消息。

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

下面的答案可以通过启用TLS 1.0,SSL 2和SSL3来帮助您诊断问题,但是要非常清楚,您不想长期这样做,因为这三个协议都被视为不安全且should no longer be used

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

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.0\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.1\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Client] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS
1.2\Server] "DisabledByDefault"=dword:00000000 "Enabled"=dword:00000001

如果这样做没有效果,您也可以尝试添加SSL 2.0条目:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server]
"DisabledByDefault"=dword:00000000
"Enabled"=dword:00000001

要清楚,这不是一个很好的解决方案,正确的解决方案是使调用方使用TLS 1.2,但是以上内容可以帮助诊断出这是问题所在。

您可以使用以下Powershell脚本加快添加这些注册表项的速度:

$ProtocolList       = @("SSL 2.0","SSL 3.0","TLS 1.0", "TLS 1.1", "TLS 1.2")
$ProtocolSubKeyList = @("Client", "Server")
$DisabledByDefault = "DisabledByDefault"
$Enabled = "Enabled"
$registryPath = "HKLM:\\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\"

foreach($Protocol in $ProtocolList)
{
    Write-Host " In 1st For loop"
        foreach($key in $ProtocolSubKeyList)
        {         
            $currentRegPath = $registryPath + $Protocol + "\" + $key
            Write-Host " Current Registry Path $currentRegPath"
            if(!(Test-Path $currentRegPath))
            {
                Write-Host "creating the registry"
                    New-Item -Path $currentRegPath -Force | out-Null             
            }
            Write-Host "Adding protocol"
                New-ItemProperty -Path $currentRegPath -Name $DisabledByDefault -Value "0" -PropertyType DWORD -Force | Out-Null
                New-ItemProperty -Path $currentRegPath -Name $Enabled -Value "1" -PropertyType DWORD -Force | Out-Null    
    }
}
 
Exit 0

这是Microsoft帮助页面上Set up TLS for VMM的脚本的修改版本。 basics.net article是最初使我想到这些设置的页面。

答案 8 :(得分:2)

只需添加:

ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

答案 9 :(得分:1)

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

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

<system.web>
        <compilation debug="true" targetFramework="4.7.2" />
        <httpRuntime targetFramework="4.7.2"  maxRequestLength="102400" executionTimeout="3600"/>
</system.web>

答案 10 :(得分:0)

使用HTTP调试代理可能导致此问题 - 例如Fiddler。

我正在从本地文件(Apple.com的身份验证)加载PFX证书,但由于Fiddler无法通过此证书,因此失败了。

尝试禁用Fiddler进行检查,如果这是解决方案,那么您可能需要在您的计算机上安装证书,或者以Fiddler可以使用的方式安装证书。

答案 11 :(得分:0)

以下代码解决了我的问题:

request.ProtocolVersion = HttpVersion.Version10; // THIS DOES THE TRICK
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;

答案 12 :(得分:0)

如果可以帮助某人,我们的问题就是缺少证书。环境是带有.Net 4.6的Windows Server 2016 Standard。

有一个自托管的WCF服务https URI,对其执行Service.Open()不会出错。另一个线程将继续访问https://OurIp:443/OurService?wsdl以确保该服务可用。访问曾经失败的WSDL:

基础连接已关闭:发送中发生意外错误。

ServicePointManager.SecurityProtocol 与适用的设置一起使用不起作用。使用服务器角色和功能也无济于事。然后介入SE的 Jaise George ,在几分钟内解决了这个问题。 Jaise 在IIS中安装了一个自签名证书,以此来解决问题。这是他为解决该问题所做的事情:

(1)打开IIS管理器(inetmgr) (2)单击左侧面板中的服务器节点,然后双击“服务器证书”。 (3)单击右侧面板上的“创建自签名证书”,然后键入任何想要的友好名称。 (4)单击左侧面板中的“默认网站”,单击右侧面板中的“绑定”,单击“添加”,选择“ https”,选择刚创建的证书,然后单击“确定”。 (5)访问https URL,应该可以访问。

答案 13 :(得分:0)

您只需将应用程序版本从4.0更改为4.6,然后发布这些代码即可。

还添加以下代码行:

httpRequest.ProtocolVersion = HttpVersion.Version10; 
ServicePointManager.Expect100Continue = true;
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;