因为win7时,ssl支持的默认版本为TLS 1.0 (更老的xp系统用的SSL2.0),较新的服务器已经使用TLS 1.1、TLS 1.2和TLS 1.3
客户端和服务器TLS版本不对,互相看不顺眼,所以发生 ERROR_WINHTTP_SECURE_FAILURE 错误。
如果你是开发C++,那么可以在 WinHttpOpen 产生session之后进行如下操作:
//头部定义
#ifndef WINHTTP_FLAG_SECURE_PROTOCOL_TLS1
#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 0x0000080
#endif
#ifndef WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1
#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 0x0000200
#endif
#ifndef WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2 0x0000800
#endif
//以上为头部定义
DWORD dwSslOption = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1 |
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1 |
WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2;
//dwSslOption = 0x00000a80
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &dwSslOption, sizeof(dwSslOption));
上边计算出的DWORD值为 0x00000a80
另外一种原因是证书过期或证书域名不搭产生的ERROR_WINHTTP_SECURE_FAILURE 错误,
可以在 WinHttpOpenRequest 之后加入下面代码忽略证书错误继续访问:
DWORD dwFlags;
dwFlags = SECURITY_FLAG_IGNORE_UNKNOWN_CA | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;
WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwFlags, sizeof(dwFlags));
这样就修复了这类错误。
如果你不是开发者,要让系统支持新的安全协议,如下操作:
第1步打补丁:
https://www.catalog.update.microsoft.com/search.aspx?q=KB3020369
https://www.catalog.update.microsoft.com/search.aspx?q=KB3125574
https://www.catalog.update.microsoft.com/search.aspx?q=kb3140245
第2步小工具修改注册表
参考自微软说明:
根据上边说明添加win7的注册表两个项目,分别是For TLS 1.1和For TLS 1.2。
附,注册表快速跳转指定路径的小工具
https://docs.microsoft.com/zh-cn/sysinternals/downloads/regjump