在 Windows 中连接 SQL Server 时,应用程序遇到强制关闭 TLS 连接错误

本文可帮助解决应用程序尝试打开与SQL Server的连接时出现的问题。

适用于:Windows Server 2019,Windows Server 2016
原始 KB 编号: 4557473

症状

当应用程序尝试打开与SQL Server的连接时,将显示以下错误消息之一:

已成功与服务器建立连接,但是在登录过程中发生错误。 (提供程序:SSL 提供程序,错误:0 - 远程主机强行关闭了现有连接。)

已成功与服务器建立连接,但在登录前握手期间发生了错误。 (提供程序:TCP 提供程序,错误:0 - 远程主机强行关闭了现有连接。)

如果在服务器上启用了 SChannel 日志记录 ,则会出现 事件 ID 36888, (在出现问题时) 生成了严重警报

注意

  • 根据所使用的提供程序或驱动程序,错误消息可能会略有不同。
  • 当在 Windows Server 2012 R2 上运行的应用程序尝试连接到在 Windows Server 2019 上运行SQL Server时,也会出现此问题。
  • 其他客户端-服务器应用程序可能会遇到类似的问题。

原因

Windows 10版本 1511 及更高版本的 Windows(包括 Window Server 2016 或 Windows 10、安装了 2 月 25 日发布的更新的版本 1607 或更高版本的更新)包含前导零更新。 同时,之前发布的所有 Windows 版本不包含前导零更新。

TLS 客户端和服务器需要以完全相同的方式计算密钥,否则它们会获得不同的结果。 如果 TLS 客户端和 TLS 服务器以不同的方式计算前导零,TLS 连接会随机失败。

Diffie-Hellman 密钥交换 组具有前导零时,未修补的计算机可能会不考虑填充的零来错误地计算 mac。 此问题通常在与非基于 Windows 的加密实现交互时出现,并可能导致间歇性协商失败。

使用 TLS_DHE 密码套件在客户端和服务器之间协商安全 TLS 握手时,将返回错误消息。 可以在“Server Hello”数据包中标识某个受影响的密码套件的使用。 有关详细信息,请参阅“更多信息”部分中的网络代码片段。

解决方案

若要解决此问题,请确保连接中涉及的客户端和服务器都运行的 Windows 都安装了TLS_DHE的前导零修补程序。 建议安装更新,因为它们增强了对TLS_DHE规范的符合性。

下面根据安装的更新列出操作系统版本。

包含针对TLS_DHE的前导零修补程序的 Windows 版本

  • Windows Server 2016版本 1607
    • KB 4537806:2020 年 2 月 25 日-KB4537806 (操作系统内部版本 14393.3542)
    • KB 4540670:2020 年 3 月 10 日-KB4540670 (操作系统内部版本 14393.3564)
    • 取代相应操作系统版本的KB4537806和KB4540670的汇报
  • Windows Server 2019 RTM 及更高版本。
  • Windows 10、版本 1511 和更高版本的Windows 10 (请参阅发布历史记录)

不包含针对TLS_DHE的前导零修补程序的 Windows 版本

  • Windows Server 2016,未应用修补程序 KB 4537806 和 KB 4540670的版本 1607 服务器。
  • Windows 10版本 1507
  • Windows 8.1
  • Windows 7
  • Windows Server 2012 R2 和早期版本的 Windows Server

解决方法

如果无法更新 Windows,作为解决方法,可以使用两种方法之一禁用TLS_DHE密码。

使用组策略

可以使用 组策略 禁用TLS_DHE_* 密码。 若要配置“SSL 密码套件顺序”组策略,请参阅 确定 Schannel 密码 套件的优先级。

策略 URL:计算机配置 -> 管理模板 -> 网络 -> SSL 配置设置
策略设置:SSL 密码套件顺序设置。

使用 PowerShell 脚本

foreach ($CipherSuite in $(Get-TlsCipherSuite).Name)
{
    if ( $CipherSuite.substring(0,7) -eq "TLS_DHE" )
    {
       "Disabling cipher suite: " + $CipherSuite
       Disable-TlsCipherSuite -Name $CipherSuite
    }
    else
    {
        "Existing enabled cipher suite will remain enabled: " + $CipherSuite
    }
}

更多信息

可以确认在建立连接期间遇到此问题。 出现此问题时,可以在服务器上的网络跟踪中看到以下顺序。

1103479 <DateTime> 382.4104867 <Application IP> <Server IP> TCP:Flags=CE....S., SrcPort=62702, DstPort=1433, PayloadLen=0, Seq=829174047, Ack=0, Win=8192 ( Negotiating scale factor 0x8 ) = 8192  
1103486 <DateTime> 382.4105589 <Server IP> <Application IP> TCP: [Bad CheckSum]Flags=...A..S., SrcPort=1433, DstPort=62702, PayloadLen=0, Seq=267349053, Ack=829174048, Win=65535 ( Negotiated scale factor 0x8 ) = 16776960  
1103493 <DateTime> 382.4113628 <Application IP> <Server IP> TCP:Flags=...A...., SrcPort=62702, DstPort=1433, PayloadLen=0, Seq=829174048, Ack=267349054, Win=513 (scale factor 0x8) = 131328  
1103515 <DateTime> 382.4117349 <Application IP> <Server IP> TDS:Prelogin, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 1, Flags=...AP..., SrcPort=62702, DstPort=1433, PayloadLen=88, Seq=829174048 - 829174136, Ack=267349054, Win=131328  
1103525 <DateTime> 382.4118186 <Server IP> <Application IP> TDS:Response, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 1, Flags=...AP..., SrcPort=1433, DstPort=62702, PayloadLen=48, Seq=267349054 - 267349102, Ack=829174136, Win=2102272  
1103547 <DateTime> 382.4128101 <Application IP> <Server IP> TLS:TLS Rec Layer-1 HandShake: Client Hello.  
1103584 <DateTime> 382.4151314 <Server IP> <Application IP> TLS:TLS Rec Layer-1 HandShake: Server Hello. Certificate. Server Key Exchange. Server Hello Done.  
1103595 <DateTime> 382.4161185 <Application IP> <Server IP> TCP:Flags=...A...., SrcPort=62702, DstPort=1433, PayloadLen=0, Seq=829174322, Ack=267351024, Win=513 (scale factor 0x8) = 131328  
1103676 <DateTime> 382.4782629 <Application IP> <Server IP> TLS:TLS Rec Layer-1 HandShake: Client Key Exchange.; TLS Rec Layer-2 Cipher Change Spec; TLS Rec Layer-3 HandShake: Encrypted Handshake Message.  
1103692 <DateTime> 382.4901904 <Server IP> <Application IP> TCP:[Segment Lost] [Bad CheckSum]Flags=...A...F, SrcPort=1433, DstPort=62702, PayloadLen=0, Seq=267351024, Ack=829174648, Win=8210 (scale factor 0x8) = 2101760  
1103696 <DateTime> 382.4918048 <Application IP> <Server IP> TCP:Flags=...A...., SrcPort=62702, DstPort=1433, PayloadLen=0, Seq=829174648, Ack=267351025, Win=513 (scale factor 0x8) = 131328  
1103718 <DateTime> 382.4931068 <Application IP> <Server IP> TCP:Flags=...A...F, SrcPort=62702, DstPort=1433, PayloadLen=0, Seq=829174648, Ack=267351025, Win=513 (scale factor 0x8) = 131328  
1103723 <DateTime> 382.4931475 <Server IP> <Application IP> TCP: [Bad CheckSum]Flags=...A...., SrcPort=1433, DstPort=62702, PayloadLen=0, Seq=267351025, Ack=829174649, Win=8210 (scale factor 0x8) = 2101760  

检查服务器 Hello 数据包以查看正在使用的密码套件:

Frame: Number = 1103584, Captured Frame Length = 2093, MediaType = NetEvent  
+NetEvent:  
+MicrosoftWindowsNDISPacketCapture: Packet Fragment (1976 (0x7B8) bytes)  
+Ethernet: Etype = Internet IP (IPv4),DestinationAddress:[00-00-0C-9F-F4-5C],SourceAddress:[00-1D-D8-B8-3A-7B]  
+Ipv4: Src = <Server IP>, Dest = <Application IP>, Next Protocol = TCP, Packet ID = 16076, Total IP Length = 0  
+Tcp: [Bad CheckSum]Flags=...AP..., SrcPort=1433, DstPort=62702, PayloadLen=1938, Seq=267349102 - 267351040, Ack=829174322, Win=8211 (scale factor 0x8) = 2102016  
+Tds: Prelogin, Version = 7.300000(No version information available, using the default version), SPID = 0, PacketID = 0, Flags=...AP..., SrcPort=1433, DstPort=62702, PayloadLen=1938, Seq=267349102 - 267351040, Ack=829174322, Win=2102016  
TLSSSLData: Transport Layer Security (TLS) Payload Data  
-TLS: TLS Rec Layer-1 HandShake: Server Hello. Certificate. Server Key Exchange. Server Hello Done.  
-TlsRecordLayer: TLS Rec Layer-1 HandShake:  
ContentType: HandShake:  
+Version: TLS 1.2  
Length: 1909 (0x775)  
-SSLHandshake: SSL HandShake Server Hello Done(0x0E)  
HandShakeType: ServerHello(0x02)  
Length: 81 (0x51)  
-ServerHello: 0x1  
+Version: TLS 1.2  
+RandomBytes:  
SessionIDLength: 32 (0x20)  
SessionID: Binary Large Object (32 Bytes)  
TLSCipherSuite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 { 0x00, 0x9F }  
CompressionMethods: 0 (0x0)  
ExtensionsLength: 9 (0x9)  
+ServerHelloExtension: Unknown Extension Type  
+ServerHelloExtension: Renegotiation Info(0xFF01)  
HandShakeType: Certificate(0x0B)  
Length: 778 (0x30A)  
+Cert: 0x1  
HandShakeType: Server Key Exchange(0x0C)  
Length: 1034 (0x40A)  
ServerKeyExchange: Binary Large Object (1034 Bytes)  
HandShakeType: Server Hello Done(0x0E)  
Length: 0 (0x0)  
+Tds: Prelogin, Version = 7.300000(No version information available, using the default version), Reassembled Packet

参考

有关详细信息,请参阅以下文章: