解决 TLS 1.0 问题(第 2 版)
本文档先提供了最新指南来介绍如何快速识别和删除基于 Microsoft 操作系统构建的软件中的传输层安全性 (TLS) 协议版本 1.0 依赖项,然后详细介绍了产品更改和 Microsoft 提供的可保护你的客户和在线服务的新功能。 其目标用途是作为迁移到 TLS 1.2+ 网络环境的计划的一个创建起始点。 尽管此处讨论的解决方案可以进行延伸和帮助删除非 Microsoft 操作系统或加密库中的 TLS 1.0 使用情况,但它们并非本文的重点。
TLS 1.0 是一种安全协议,首次定义于 1999 年,用于通过计算机网络建立加密通道。 自 Windows XP/Server 2003 起,Microsoft 已支持此协议。 尽管新式 OS 不再使用默认安全协议,但 TLS 1.0 仍支持后向兼容性。 由于不断更新的法规要求和 TLS 1.0 中的新安全漏洞,企业有理由完全禁用 TLS 1.0。
Microsoft 建议客户尽可能地删除环境中的 TLS 1.0 依赖项以及禁用操作系统级别的 TLS 1.0,以便避开此问题。 鉴于 TLS 1.0 在软件行业中已受到长时间的支持,因此强烈建议任何 TLS 1.0 弃用计划都应考虑以下事项:
进行代码分析以查找/修复 TLS 1.0 或旧安全协议的硬编码实例。
进行网络终结点扫描和流量分析,以便识别使用 TLS 1.0 或旧协议的操作系统。
在禁用 TLS 1.0 的情况下,对整个应用程序堆栈进行完整的回归测试。
默认情况下,将旧版操作系统和开发库/框架迁移到能够协商 TLS 1.2 的版本。
在企业使用的操作系统上进行兼容性测试,以识别任何 TLS 1.2 支持问题。
与你自己的业务合作伙伴和客户进行协调,以通知他们你要弃用 TLS 1.0。
了解在禁用 TLS 1.0 后,哪些客户端可能无法再连接到服务器。
本文的目的是提供一些建议来帮助消除在禁用 TLS 1.0 时的技术障碍,同时增加此更改对客户的影响的了解。 完成此类调查可帮助降低 TLS 1.0 中下一个安全漏洞对业务的影响。 出于本文档的目的,对弃用 TLS 1.0 的引用也包含 TLS 1.1。
企业软件开发人员在策略上需要采用未来更加安全且敏捷的解决方案(也称为“加密灵活性”)来处理将来的安全协议风险。 尽管本文档推荐使用敏捷解决方案来消除 TLS 硬编码,但在本文档介绍范围之外,还有更广泛的“加密灵活性”解决方案。
Microsoft 的 TLS 1.0 实现的当前状态
Microsoft 的 TLS 1.0 实现没有已知的安全漏洞。 由于将来可能出现协议降级攻击和非特定于 Microsoft 实现的其他 TLS 1.0 漏洞,因此建议尽可能删除早于 TLS 1.2 的所有安全协议上的依赖项 (TLS 1.1/1.0/ SSLv3/SSLv2)。
在计划向 TLS 1.2+ 迁移时,开发人员和系统管理员应了解在其员工和合作伙伴开发的应用程序中进行协议版本硬编码的可能性。 此处的硬编码是指 TLS 版本固定为已过时且安全性低于较新版本的版本。 如果未修改相关程序,则无法使用比硬编码版本更新的 TLS 版本。 如果未进行源代码更改和软件更新部署,则无法解决此类问题。 协议版本硬编码过去常用于测试和可支持性目的,因为许多不同的浏览器和操作系统具有不同级别的 TLS 支持。
Windows 支持的 TLS 版本
许多操作系统都具有过时的默认 TLS 版本或需要考虑的支持上限。
图 1:按 OS 版本显示的安全协议支持
Windows 操作系统 | SSLv2 | SSLv3 | TLS 1.0 | TLS 1.1 | TLS 1.2 | TLS 1.3 |
---|---|---|---|---|---|---|
Windows Vista | Enabled | 已启用 | 已启用 | 不支持 | 不支持 | 不支持 |
Windows Server 2008 | Enabled | 已启用 | 已启用 | 已禁用* | 已禁用* | 不支持 |
Windows 7 (WS2008 R2) | Enabled | 已启用 | 已启用 | 已禁用* | 已禁用* | 不支持 |
Windows 8 (WS2012) | 已禁用 | 已启用 | 已启用 | 已启用 | 已启用 | 不支持 |
Windows 8.1 (WS2012 R2) | 已禁用 | 已启用 | 已启用 | 已启用 | 已启用 | 不支持 |
Windows 10 | 已禁用 | 已启用 | 已启用 | 已启用 | 已启用 | 不支持 |
Windows 11 | 已禁用 | 已启用 | 已启用 | 已启用 | 已启用 | 已启用 |
Windows Server 2016 | 不支持 | 已禁用 | 已启用 | 已启用 | 已启用 | 不支持 |
Windows Server 2016 | 不支持 | 已禁用 | 已启用 | 已启用 | 已启用 | 不支持 |
Windows Server 2019 | 不支持 | 已禁用 | 已启用 | 已启用 | 已启用 | 不支持 |
Windows Server 2019 GS 版本 | 不支持 | 已禁用 | 已禁用 | 已禁用 | Enabled | 不支持 |
Windows Server 2022 | 不支持 | 已禁用 | 已禁用 | 已禁用 | 已启用 | 已启用 |
Windows Server 2019 GS 版本符合 Microsoft SDL,TLS 1.2 仅具有受限的密码套件集。
Windows Server 2022 版本符合 Microsoft SDL,TLS 1.2 和 TLS 1.3 仅具有受限的密码套件集。
可通过此可选的 Windows 更新包在 Windows Server 2008 上启用 TLS 1.1/1.2。
有关在 IE/Edge 弃用 TLS 1.0/1.1 的详细信息,请参阅在 Microsoft Edge 和 Internet Explorer 11 中实现新式 TLS 连接、Microsoft Edge 面临的影响站点兼容性的更改以及在新的 Edge 浏览器中禁用 TLS/1.0 和 TLS/1.1
连接到在线服务时,通过参阅 Qualys SSL 实验室上的“握手模拟”可快速确定不同客户端将请求的 TLS 版本。 此模拟涵盖了跨制造商的客户端 OS/浏览器组合。 有关连接到 www.microsoft.com 时显示由各种模拟客户端 OS/浏览器组合协商的 TLS 协议版本的详细示例,请参阅本文档末尾的附录 A。
如果尚未完成此操作,强烈建议对你的企业、客户和合作伙伴(后两者通过扩展/通信或至少使用 HTTP 用户代理字符串集合)使用的操作系统开列清单。 此清单可通过企业网络边缘的流量分析进行进一步补充。 在这种情况下,流量分析将生成由连接到服务的客户/合作伙伴成功协商的 TLS 版本,但流量本身仍将保持加密状态。
Microsoft 为消除 TLS 1.0 依赖项而进行的过程改进
自本文档的 v1 版本起,Microsoft 已提供许多软件更新和新功能来支持弃用 TLS 1.0。 这些设置包括:
IIS 自定义日志 - 用于关联客户端 IP/用户代理字符串、服务 URI、TLS 协议版本和密码套件。
- 通过此日志记录,管理员最终可以量化客户暴露给弱 TLS 的情况。
SecureScore - 为帮助 Office 365 租户管理员确定自己的弱 TLS 使用情况,在 2018 年 10 月 TLS 1.0 在 Office 365 中退出支持时,我们构建了 SecureScore 来共享信息。
此门户向 Office 365 租户管理员提供有价值的信息,他们需要这些信息来与可能不清楚自己的 TLS 1.0 依赖项的客户联系。
有关详细信息,请访问 https://securescore.microsoft.com/。
.Net Framework 更新 - 用于清除应用级别的硬编码,并阻止框架继承的 TLS 1.0 依赖项。
开发人员指南和软件更新已发布,可帮助客户识别和清除弱 TLS 的 .Net 依赖项:.NET Framework 中的传输层安全性 (TLS) 最佳做法
- 供参考:需要对面向 .NET 4.5 或更低版本的所有应用进行修改才能支持 TLS 1.2。
TLS 1.2 已向后迁移到 Windows Server 2008 SP2 和 XP POSReady 2009 以帮助客户完成之前的任务。
2019 年初将发布更多公告,相关信息会在本文档的后续更新中进行传达。
在代码中查找并修复 TLS 1.0 依赖项
对于使用 Windows OS 提供的加密库和安全协议的产品,以下步骤可帮助确定应用程序中任何硬编码的 TLS 1.0 的使用情况:
确定 AcquireCredentialsHandle() 的所有实例。 这可以帮助审阅者更了解可能在其中对 TLS 进行硬编码的代码块。
查看硬编码 TLS 的 SecPkgContext_SupportedProtocols 和 SecPkgContext_ConnectionInfo 结构的任何实例。
在本机代码中,将 grbitEnabledProtocols 的任何非零赋值都设置为零。 这使得操作系统可使用其默认 TLS 版本。
如果启用了 FIPS 模式,请禁用它。因为它可能与本文档中显式禁用 TLS 1.0/1.1 所需的设置相冲突。 有关详细信息,请参阅附录 B。
使用 Server 2012 或更低版本上托管的 WinHTTP 更新和重新编译任何应用程序。
托管应用 - 针对最新的 .NET Framework 版本进行重新生成和重定向
应用程序必须通过 WinHttpSetOption 添加代码以支持 TLS 1.2
若要涵盖所有基础信息,请扫描以下模式的源代码和在线服务配置文件,这些模式与 TLS 硬编码中常用的枚举类型值相对应:
SecurityProtocolType
SSLv2、SSLv23、SSLv3、TLS1、TLS 10、TLS11
WINHTTP_FLAG_SECURE_PROTOCOL_
SP_PROT_
NSStreamSocketSecurityLevel
PROTOCOL_SSL 或 PROTOCOL_TLS
在上述所有情况中,推荐的解决方案是删除所选的硬编码协议版本并遵从操作系统默认值。 如果使用的是 DevSkim,请单击此处以查看涵盖上述检查内容的规则(这些规则可用于你自己的代码)。
更新 Windows PowerShell 脚本或相关注册表设置
Windows PowerShell 使用 .NET Framework 4.5,TLS 1.2 未作为可用协议包含在内。 若要解决此问题,可使用两种解决方案:
修改所讨论的脚本,使其包含以下内容:
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12;
将系统范围的注册表项添加到(例如通过组策略)任何需要从 .NET 应用建立 TLS 1.2 连接的计算机。 这会使 .NET 使用将 TLS 1.2 添加为可用协议的“系统默认”TLS 版本,并且它将允许脚本在 OS 支持将来的 TLS 版本时使用这些版本。 (例如 TLS 1.3)
reg add HKLM\SOFTWARE\Microsoft.NETFramework\v4.0.30319 /v SystemDefaultTlsVersions /t REG_DWORD /d 1 /f /reg:64
reg add HKLM\SOFTWARE\Microsoft.NETFramework\v4.0.30319 /v SystemDefaultTlsVersions /t REG_DWORD /d 1 /f /reg:32
解决方案 (1) 和 (2) 互相排斥,这意味着无需同时实现它们。
使用最新的 .Net Framework 版本重新生成/重定向托管应用程序
使用 4.7 之前的 .NET framework 版本的应用程序可能存在一些限制,这些限制将支持上限设定为 TLS 1.0 而不考虑基础的 OS 默认值。 有关详细信息,请参阅下图和 .NET Framework 中的传输层安全性 (TLS) 最佳实践。
SystemDefaultTLSVersion 优先于 TLS 版本的应用级定向。 建议的最佳做法是始终遵从 OS 默认 TLS 版本。 它还是唯一一个可使应用利用未来 TLS 1.3 支持的加密灵活解决方案。
如果面向的是较旧版本的 .NET Framework(如 4.5.2 或 3.5),则默认情况下,应用程序将使用不推荐使用的较旧协议,如 SSL 3.0 或 TLS 1.0。 强烈建议升级到较新版本的 .NET Framework(如 NET Framework 4.6)或为“UseStrongCrypto”设置相应的注册表项。
使用 TLS 1.2+ 进行测试
按照上一部分建议的修复方法,应对产品进行回归测试,以检查协议协商错误以及与企业中其他操作系统的兼容性。
回归测试中最常见的问题将是 TLS 协商失败,原因是尝试从不支持 TLS 1.2 的操作系统或浏览器进行客户端连接。
- 例如,由于 Vista 支持的最高 TLS 版本为 1.0,因此 Vista 客户端将无法与为 TLS 1.2+ 配置的服务器协商 TLS。 应在 TLS 1.2+ 环境中升级或取消授权该客户端。
使用基于证书的相互 TLS 身份验证的产品可能需要额外的回归测试,因为与 TLS 1.0 相关联的证书选择代码的表现力弱于 TLS 1.2。
- 如果产品与非标准位置(Windows 中标准命名的证书存储之外)中的证书协商 MTLS,则该代码可能需要更新以确保正确获取证书。
应评审服务依赖项以检查是否存在问题。
与第 3 方服务进行交互操作的任何服务都应与这些第 3 方进行额外的互操作测试。
使用中的任何非 Windows 应用程序或服务器操作系统都需要进行调查/确认它们是否支持 TLS 1.2。 确定这一点的最简单方式是进行扫描。
用于测试在线服务更改的简单蓝图包括以下内容:
扫描生产环境系统,以确定不支持 TLS 1.2 的操作系统。
扫描源代码和在线服务配置文件以查找硬编码 TLS,如“在代码中查找并修复 TLS 1.0 依赖项”中所述。
根据需要更新/重新编译应用程序:
托管应用
针对最新的 .NET Framework 版本重新生成。
为使用 OS 默认设置,请验证是否 SSLProtocols 枚举的任何使用情况均已设为 SSLProtocols.None。
WinHTTP 应用 - 使用 WinHttpSetOption 重新生成以支持 TLS 1.2
在预生产或过渡环境中开始测试,通过注册表禁用所有早于 TLS 1.2 的安全协议。
修复测试中遇到的 TLS 硬编码的任何剩余实例。 重新部署软件并执行新的回归测试运行。
向合作伙伴通知 TLS 1.0 弃用计划
解决 TLS 硬编码并完成操作系统/开发框架更新后,如果选择弃用 TLS 1.0,则需要与客户和合作伙伴进行协调:
与合作伙伴/客户进行早期联系对于成功执行 TLS 1.0 弃用至关重要。 至少应包含博客文章、白皮书或其他 Web 内容。
每位合作伙伴都需要通过上述部分中所述的操作系统/代码扫描/回归测试计划,评估其自己的 TLS 1.2 就绪情况。
结束语
删除 TLS 1.0 依赖项是端到端驱动的一个复杂问题。 Microsoft 和行业合作伙伴目前正在采取行动来确保在默认情况下我们的整个产品堆栈都能更加安全,无论是从 OS 组件和开发框架还是在其基础上构建的应用程序/服务。 按照本文档提供的建议进行操作,可帮助你的企业制定正确的路线,并了解将面临的挑战。 它还将帮助你的客户为过渡做好更充分的准备。
附录 A:用于连接到 www.microsoft.com 的各种客户端的握手模拟(由 SSLLabs.com 提供)
附录 B:在保留 FIPS 模式的同时弃用 TLS 1.0/1.1
如果网络需要 FIPS 模式,但你仍想弃用 TLS 1.0/1.1,请按照以下步骤操作:
通过注册表配置 TLS 版本,方式是对于不需要的 TLS 版本,将“已启用”设为零。
通过组策略禁用 Curve 25519(仅限 Server 2016)。
使用算法禁用相关 FIPS 出版物不允许的所有密码套件。 对于 Server 2016(假设默认设置有效),这意味着禁用 RC4、PSK 和 NULL 密码。
参与者/鸣谢人
Mark Cartwright
Bryan Sullivan
Patrick Jungles
Michael Scovetta
Tony Rice
David LeBlanc
Mortimer Cook
Daniel Sommerfeld
Andrei Popov
Michiko Short
Justin Burke
Gov Maharaj
Brad Turner
Sean Stevenson