Windows 7 以及 .NET 的 TLS 兼容性设置
重要提示:
在进行任何注册表操作前,您应先备份系统注册表文件,以便在出现问题时能够恢复到原始注册表状态。作者不对使用本文所述的方法或附件造成的任何后果承担任何责任。
一、起源
2016年使用易语言写了一个能调用某热敏打印机远程打印API的程序,由于年久失修,在未知原因的情况下就不能使用了。2022年由于有用户仍然依赖这个程序(群众的呼声),于是用C#.NET重写了程序,但在2024年又突然出现无法发送请求的故障,报错提示“连接被远程服务器关闭”。
二、探索
经过排查,发现是对方的API服务禁用了SSL2、SSL3、TLS1.0、TLS1.1这些协议,只保留了TLS1.2、TLS1.3,由于Windows 7默认禁用TLS1.1、TLS1.2协议,因此程序无法建立https安全连接。
在未修改代码的情况下重新编译了程序,观察到程序在Windows 10及Windows 11系统上已经能够正确发送请求,但在Windows 7系统仍然无法发送请求。经过查阅微软官方文档发现,Windows 7在更新KB3140245补丁后拥有对TLS1.1/TLS1.2的支持,但注册表中默认禁用,兼容性参见下表(微软文档链接)。
注意:Windows 7系列系统必须更新KB3140245补丁才能拥有对TLS1.1/TLS1.2的支持。
下表中的✅表示支持,🚫表示支持但默认禁用,❌表示不支持。
三、实践
问题一
如果是已经无人维护的.NET应用,没有人对其进行更新,我们能否通过其他方式解决?
查阅微软文档,发现我们可以通过配置注册表的SchUseStrongCrypto值来启用强加密(强制使用TLS 1.2和TLS 1.1)。
要启用这一项注册表设置,我们需要执行以下注册表命令:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v2.0.50727" /v "SchUseStrongCrypto" /t REG_DWORD /d 1 /f >nul
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319" /v "SchUseStrongCrypto" /t REG_DWORD /d 1 /f >nul对于64位的操作系统,还应执行以下注册表命令:
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v2.0.50727" /v "SchUseStrongCrypto" /t REG_DWORD /d 1 /f >nul
reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\v4.0.30319" /v "SchUseStrongCrypto" /t REG_DWORD /d 1 /f >nul执行上述注册表命令后,在Windows 10及Windows 11系统上进行测试,发现曾经编译的无法发送请求的程序已经恢复正常工作,但在Windows 7系统上问题依旧,仍然提示连接被远程服务器关闭。
问题二
查阅微软文档,发现在Windows 7系列系统上默认禁用TLS 1.1/TLS 1.2协议,因此我们仍然需要在Windows注册表中配置Schannel协议才能启用。有关详细信息,可以参阅TLS 注册表设置 - Schannel。
要启用Schannel协议的TLS1.1、TLS1.2并禁用SSL2.0,我们需要执行以下注册表命令:
::禁用SSL2.0
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" /v "DisabledByDefault" /t REG_DWORD /d 0 /f >nul
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client" /v "Enabled" /t REG_DWORD /d 0 /f >nul
::启用TLS1.2
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" /v "DisabledByDefault" /t REG_DWORD /d 0 /f >nul
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Client" /v "Enabled" /t REG_DWORD /d 1 /f >nul
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" /v "DisabledByDefault" /t REG_DWORD /d 0 /f >nul
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server" /v "Enabled" /t REG_DWORD /d 1 /f >nul
::启用TLS1.1
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" /v "DisabledByDefault" /t REG_DWORD /d 0 /f >nul
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client" /v "Enabled" /t REG_DWORD /d 1 /f >nul
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" /v "DisabledByDefault" /t REG_DWORD /d 0 /f >nul
reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server" /v "Enabled" /t REG_DWORD /d 1 /f >nul注意:无需在Windows 8及以上的系统执行这些命令,仅需运行在Windows Server 2008 with Service Pack 2 (SP2)、Windows 7/Windows Server 2008 R2。
执行上述注册表命令后,之前请求报错的软件已经可以正常运行了。至此问题解决。
为方便使用,我把以上修复命令制作成了批处理文件,根据系统判断所需解决方案,支持一键开启和关闭。
批处理文件下载:https://blog-uss.fhzdcj.cn/blog/upload/dotNetTLSEnable_1740211867264.bat