手机和操作系统

A fatal alert was received:Schannel 36887 等事件和错误码

作者: · 最后核实

报错信息A fatal alert was received from the remote endpoint. The TLS protocol defined fatal alert code is 40. (Schannel Event ID 36887)

Schannel 报错是 Windows 内置安全组件报告 TLS 失败的方式。 在服务器和电脑上表现为系统日志里的事件(36887、36888、36874、36871 等),在 curl、Git、PowerShell、.NET 等程序里表现为 SEC_E_*、CRYPT_E_* 错误码。每个代码都指向一类具体原因:对方发来的告警、缺少协议或套件,或者证书问题。

先判断是网站的问题还是你设备的问题

服务器检测不通过就修服务器,检测通过就查这台 Windows 的协议设置和信任库。客户端报错时,先用 SSL 检测 查服务器:

curl ssl.sh/example.com
  • 服务器检测不通过:修服务器(证书、证书链、协议)。
  • 服务器检测通过:问题在这台 Windows 上,常见的是 TLS 版本被禁用、缺根证书、代理拦截了吊销检查,或者 HTTPS 被拦截。

如果是 IIS、远程桌面服务器上的事件,通常是客户端太老或配置不对,看告警码决定改哪一边。

原因

Schannel 报错按代码分 6 类:36887/36888 看告警码,36874 是没有共同套件,36871 是协议被禁用,其余是根证书、吊销检查、域名或有效期问题。

1. 事件 36887 / 36888 带告警码

36887 是对方发来致命告警,36888 是 Windows 发出告警。看告警码:40(handshake_failure)和 70(protocol_version)指向协议或套件不匹配;42、46、48 指向证书信任问题;80 是对方内部错误。

2. 事件 36874:没有共同的加密套件

客户端提供的套件服务器全都禁用了。对比服务器的套件顺序和客户端能力,不认识的套件名用 加密套件查询 查。

3. 事件 36871,内部错误 10013

某个程序向 Schannel 请求了被注册表或组策略禁用的协议或算法,典型的是老软件要用 TLS 1.0。升级软件,或让它使用 TLS 1.2,而不是重新打开 TLS 1.0。

4. SEC_E_UNTRUSTED_ROOT(0x80090325)

证书链终点是一个 Windows 不信任的根证书:私有 CA、缺中间证书,或者公司代理的根证书没部署到这台电脑。curl 或 Git 里的样子:

schannel: next InitializeSecurityContext failed: SEC_E_UNTRUSTED_ROOT (0x80090325)

5. CRYPT_E_NO_REVOCATION_CHECK(0x80092012)/ CRYPT_E_REVOCATION_OFFLINE(0x80092013)

Windows 访问不到 CA 的 CRL 或 OCSP 服务,通常是代理或防火墙拦截了。国内企业内网、访问境外 CA 吊销地址不稳定时很常见。放行 CA 的吊销检查地址。

6. SEC_E_WRONG_PRINCIPAL(0x80090322)和 CERT_E_EXPIRED(0x800B0101)

分别是域名不符和证书过期,见 NET::ERR_CERT_COMMON_NAME_INVALID 和 NET::ERR_CERT_DATE_INVALID。

在各浏览器/系统上的样子

服务器上的 Schannel 问题出现在事件查看器的系统日志里,客户端程序则显示 SEC_E_* 或 CRYPT_E_* 错误码。

客户端 显示内容
事件查看器(系统日志,来源 Schannel) 事件 ID 36887、36888、36874、36871、36870
curl / Git for Windows(schannel 后端) SEC_E_UNTRUSTED_ROOT (0x80090325)、CRYPT_E_NO_REVOCATION_CHECK (0x80092012)
PowerShell / .NET The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel
Edge IE 模式 / 360 兼容模式 DLG_FLAGS_SEC_CERT_CN_INVALID 等代码

站长怎么修

站长要在服务器和客户端都启用 TLS 1.2,IIS 装完整证书链,公司网络里优先修信任而不是关检查。

1. 服务器和客户端都启用 TLS 1.2(支持的系统再开 TLS 1.3)。 在 Windows Server 的 HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server 和 ...\Client 下,把 Enabled 设为 1、DisabledByDefault 设为 0,然后重启。Windows Server 2022 及以后支持 TLS 1.3。

2. IIS 安装完整证书链。 导入包含中间证书的 PFX(阿里云、腾讯云下载时选 IIS 格式),并检查“中间证书颁发机构”存储。

3. 公司网络里的 Git 优先修信任,而不是关检查:

git config --global http.sslBackend schannel

用 schannel 后端时,Git 使用 Windows 证书存储,IT 部署的公司根证书就在那里。最后用 curl ssl.sh/example.com 检查服务器一侧。

常见问题

系统日志里一堆 Schannel 36887,可以不管吗?

通常可以。面向公网的服务器每天都会收到扫描器和老客户端的握手失败。只有在和真实故障时间吻合时才需要排查,并根据告警码判断原因。

curl --ssl-no-revoke 或 http.schannelCheckRevoke=false 能用吗?

只能临时用,它们会跳过证书吊销检查。在公司代理拦截了 CRL/OCSP 访问、而你信任当前网络时,可以临时这么用,但正确做法是放行 CA 的吊销检查地址。不要把它们设成长期默认。

怎么让老的 .NET Framework 程序用上 TLS 1.2?

在 HKLM\SOFTWARE\Microsoft\.NETFramework\v4.0.30319(以及 WOW6432Node 下对应位置)把 SchUseStrongCrypto 和 SystemDefaultTlsVersions 设为 1,或者把程序升级到 .NET Framework 4.7 及以上,它会跟随操作系统默认设置。很多对接银行、税务接口的老程序就是卡在这里。

资料来源

  1. Microsoft Learn:TLS 和 SSL 警报的 Schannel 错误代码
  2. Microsoft Learn:TLS 注册表设置
  3. Microsoft Learn:TLS/SSL(Schannel SSP)概述
  4. RFC 8446 第 6 节:Alert 协议