WinHttp 不会从 WinXP 上的 Amazon S3 下载

Posted

技术标签:

【中文标题】WinHttp 不会从 WinXP 上的 Amazon S3 下载【英文标题】:WinHttp doesn't download from Amazon S3 on WinXP 【发布时间】:2015-06-30 08:10:03 【问题描述】:

最近亚马逊已禁用对 S3 存储桶的 SSL 支持,这似乎会导致 Win XP SP3 出现问题。 我用这个代码

hSession = WinHttpOpen(L"MySession",
                    WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
                    WINHTTP_NO_PROXY_NAME,
                    WINHTTP_NO_PROXY_BYPASS, 0);


if (bHTTPS)

  DWORD flags = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1;
  WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS, &flags, sizeof(flags));


port = bHTTPS ? INTERNET_DEFAULT_HTTPS_PORT : INTERNET_DEFAULT_HTTP_PORT;
hConnect = WinHttpConnect(hSession, srv_w, port, 0);    
hRequest = WinHttpOpenRequest(hConnect, vrb_w, adr_w, NULL, WINHTTP_NO_REFERER, NULL,  WINHTTP_FLAG_REFRESH | (bHTTPS ? WINHTTP_FLAG_SECURE : 0));

if (bHTTPS)

  DWORD dwSecFlag = SECURITY_FLAG_IGNORE_CERT_CN_INVALID | 
                        SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | 
                        SECURITY_FLAG_IGNORE_UNKNOWN_CA | 
                        SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE;

  WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwSecFlag, sizeof(dwSecFlag));


WinHttpSendRequest(hRequest, hdr_w, (headers != NULL) ? -1 : 0, data, size, size, 0);
WinHttpReceiveResponse(hRequest, NULL);

这在 Win7 上有效,一个月前在 WinXP 上有效。但现在我收到 WinHttp 错误 12152:服务器返回无效或无法识别的响应。我启用了跟踪和日志字段有不同的错误:

17:47:47.057 ::*0000001* :: WinHttpSendRequest(0x10a0000, "", 0, 0x0, 0, 0, 0)
17:47:47.135 ::*0000001* :: "s3.amazonaws.com" resolved
17:47:47.307 ::*0000001* :: Winsock/RPC/SSL/Transport error: 0x90312 [SEC_I_CONTINUE_NEEDED]

有没有办法在不使用 3rd 方库的情况下解决这个问题? (浏览器,包括 IE,下载文件没有问题)。

【问题讨论】:

【参考方案1】:

假设您保留不安全的dwFlags,您可以关闭 HTTPS。 您完全忽略了任何 SSL 错误并允许进行大量攻击和内容操纵。

如果您不关心安全性,为什么要使用 HTTPS?

只是一个旁注: 你应该关心安全并删除这些不安全的标志。

【讨论】:

好的,我删除了那些标志,代码仍然无法在 win XP 上运行。让我们听听一些安全提示。【参考方案2】:

我也有同样的问题。我认为这可能是由在 XP 上的 WinHTTP 中选择的 SSL_RSA_WITH_3DES_EDE_SHA 密码问题引起的。试试这个作为测试: 在 XP 机器上,为键添加一个名为“Enabled”的新 DWORD 值:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\Triple DES 168/168

这会禁用该密码,似乎为我解决了这个问题。然而,这不是一个理想的解决方案,我仍然不确定潜在的问题。亚马逊使用的任何加密货币提供商可能存在问题?

【讨论】:

我现在接受您的解决方案,它确实解决了问题,但我不确定在最终用户 PC 上禁用协议是一个好主意 :) 也许稍后有人会提出更好的方法或解释根本问题。 是的,0!很抱歉遗漏了。我同意这不是一个可行的解决方案,我仍在试图找出导致该密码使连接握手失败的确切原因。 我已经发布了无需注册表修复即可工作的 WinInet 代码【参考方案3】:

我能够重做代码并使用运行良好的 WinInet。

hInternet = InternetOpen("myapp", INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
hConnect = InternetConnect(hInternet, server, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL);

const char *accept_types[] =  "*/*", NULL ;
DWORD flags = INTERNET_FLAG_NO_UI | INTERNET_FLAG_SECURE;

hRequest = HttpOpenRequest(hConnect, verb, addr, NULL, NULL, accept_types, flags, NULL);
bResults = HttpSendRequest(hRequest, headers, -1, data, size);

bResults = HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE, tmp_buf, &buf_sz, NULL);
// check for 200 here...

bResults = HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH, tmp_buf, &buf_sz, NULL);
// allocate a buffer here

INTERNET_BUFFERS buf =  sizeof(INTERNET_BUFFERS) ;
buf.lpvBuffer = &buffer[0];
buf.dwBufferTotal = content_length;

// read using InternetReadFileEx or InternetReadFile

代码没有明确的 TLS 声明,但如果服务器只支持 TLS,客户端将没有任何选择。

【讨论】:

我看到这种情况只发生在 WinHTTP - 而不是 WinInet。 IE 8(安装在 XP 机器上)也可以正常工作,但我认为它在后端使用 WinInet。

以上是关于WinHttp 不会从 WinXP 上的 Amazon S3 下载的主要内容,如果未能解决你的问题,请参考以下文章

未收到 WinHttp POST 正文

允许在没有Active Directory信任的情况下进行winhttp委派

历史上的今天4 月 8 日:WinXP 停止服务;斯卡利当上苹果 CEO;振兴学院的女程序员

在 WinXP、VisualStudio 2005 上的 boost.python“DLL 加载失败”

WinXP 上的桌面堆监视器 (dheapmon.exe) 没有数据

在 Xampp for WinXP 上的 php.ini 中启用 curl 时出现问题