【问题标题】:libcurl returns error code 77 when the CURLOPT_SSL_VERIFYPEER is not disabled当 CURLOPT_SSL_VERIFYPEER 未被禁用时,libcurl 返回错误代码 77
【发布时间】:2021-05-25 00:44:21
【问题描述】:

我对 curl 或 HTTP 请求不是很熟悉,但正在努力学习。

就我而言,我正在尝试在 C++ 中使用 libcurl(在 Windows 10 上使用 Visual Studio 2019)来执行 GET 请求。我尝试了Curl in C++ - Can't get data from HTTPS 的解决方案,但唯一对我有用的是使用以下方法禁用 SSL 对等验证:

curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);

这是我的代码:

void getPairPrice(string & pair) {
    string url(BINANCE_HOST);
    url += "/api/v3/ticker/price?symbol=";
    url += pair;
    CURL* curl;
    CURLcode res;
    std::string readBuffer;
    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET");
        curl_easy_setopt(curl, CURLOPT_URL,  url.c_str());
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_easy_setopt(curl, CURLOPT_ENCODING, "gzip");

        struct curl_slist* headers = NULL;
        headers = curl_slist_append(headers, PUBLIC_KEY_HEADER);
        headers = curl_slist_append(headers, CONTENT_TYPE_HEADER);
        curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);

        res = curl_easy_perform(curl);

        //cout << "res : " << res << endl;
        std::cout <<  "GET symbol " << pair << " price : "  << readBuffer << std::endl;
        const string jsonKey = "price";
        cout << "Price : " << extractJsonValue(readBuffer, jsonKey) << endl;
    }
    curl_easy_cleanup(curl);
    curl_global_cleanup();
}

在不禁用SSL_VERIFYPEER 选项的情况下,响应始终为 77。这对于测试来说很好,但我想知道在发布我的软件时如何解决这个问题。看来我应该以某种方式下载 PEM 格式的主机 SSL 证书并将 libcurl 指向它。

谁能帮忙?

【问题讨论】:

    标签: c++ openssl libcurl binance


    【解决方案1】:

    错误 77 是 CURLE_SSL_CACERT_BADFILE

    读取 SSL CA 证书时出现问题(路径?访问权限?)

    CURLOPT_SSL_VERIFYPEER documentation 说:

    在协商 TLS 或 SSL 连接时,服务器会发送一个表明其身份的证书。 Curl 验证证书是否真实,即您可以相信服务器就是证书所说的那个人。这种信任基于一系列数字签名,植根于您提供的证书颁发机构 (CA) 证书。 curl 使用默认的 CA 证书包(其路径在构建时确定),您可以使用 CURLOPT_CAINFO 选项或 CURLOPT_CAPATH 选项指定备用证书

    CURLOPT_SSL_VERIFYPEER开启时,验证失败证明证书真实,连接失败。如果选项为零,则无论如何,对等证书验证都会成功。

    所以是的,如果您打算验证服务器的证书,您需要向 libcurl 提供用于签署服务器证书的证书颁发机构 (CA)。如果您没有可用的 CA,则无法验证证书。

    文档还说:

    认证证书不足以确定服务器。您通常还希望确保服务器是您要与之交谈的服务器。为此使用CURLOPT_SSL_VERIFYHOST。检查证书中的主机名是否对您要连接的主机名有效,这与 CURLOPT_SSL_VERIFYPEER 选项无关。

    警告:禁用证书验证允许坏人在您不知情的情况下进行通信中间人。禁用验证会使通信不安全。仅对传输进行加密是不够的,因为您无法确定您正在与正确的端点进行通信。

    注意:即使禁用此选项,根据使用的 TLS 后端,curl 仍可能加载CURLOPT_CAINFO 中指定的证书文件。某些发行版中的 curl 默认设置可能会使用相当大的文件作为 CURLOPT_CAINFO 的默认设置,因此加载文件可能会非常昂贵,尤其是在处理许多连接时。因此,在某些情况下,您可能希望通过将 CURLOPT_CAINFO 设置为 NULL 来完全禁用验证以节省资源 - 但也请考虑上面的警告!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-02-01
      • 2014-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-17
      • 1970-01-01
      相关资源
      最近更新 更多