用于 https 读取文件的 c++ libcurl 和 SSL 设置
c++ libcurl and SSL setup for https read file
对于我的桌面软件 (Windows 7 - 10),我通过读取服务器上的文件检查版本并从中获取信息(读取 txt 文件)。这已经完成,但我不确定我是否使用正确的 SSL 设置以及是否需要为这个简单的事情提供安全性(我不确定 SSL 是如何工作的,我使用了 libcurl 示例中的一些示例)。我只读txt文件,获取信息(程序版本),仅此而已。
也许值得一提,我使用 libcurl 下载站点的二进制文件 Windows(二进制 curl 项目)。
这是我如何使用 libcurl 的部分代码:
std::stringstream isf;
CURL *curl;
CURLcode res;
/* CURL functions are function pointers because I load libcurl manually (LoadLibrary()) */
curl = curlEasyInit();
if (curl)
{
curlEasySetOpt(curl, CURLOPT_URL, "https://example.com/MyFile.txt");
curlEasySetOpt(curl, CURLOPT_WRITEFUNCTION, my_read_stream);
curlEasySetOpt(curl, CURLOPT_WRITEDATA, &isf);
// ------------------------------------------------------------------------------------------
// *** Question below ***
curlEasySetOpt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
curlEasySetOpt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // this is needed if I use CURLOPT_USE_SSL othervise it is unable to connect to https if I use CURLOPT_USE_SSL
// ------------------------------------------------------------------------------------------
res = curlEasyPerform(curl);
// ...
curlEasyCleanup(curl);
curlGlobalCleanup();
curl_easy_cleanup(curl);
}
size_t my_read_stream(void * buffer, size_t size, size_t nmemb, void * stream)
{
bool ok = false;
size_t b;
try {
std::stringstream * fs = static_cast<std::stringstream *>(stream);
b = size * nmemb;
fs->write(static_cast<char*>(buffer), b);
ok = true;
}
catch (std::exception e)
{
std::cout << "ERROR READ STREAM : " << e.what() << std::endl;
}
if (ok)
{
return b;
}
else
{
b = size * nmemb;
return b;
}
}
问题:
我能够连接 https://example.com/MyFile.txt
并在没有 SSL 设置的情况下读取文件(请参阅用注释封装的代码)。当我使用 curlEasySetOpt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
时,我无法连接到 https 站点,因为验证失败(需要一些认证),当我关闭 CURLOPT_SSL_VERIFYPEER
时,我可以连接到 https,现在的问题是:
- 此 SSL 设置(在我提供的代码中)是否足够安全以供读取
文件?
- 当我使用此 SSL 设置时,它会增加一些安全性吗?
- 当我使用时,这个简单的读取文件代码是否需要 SSL 安全性
https?
禁用 SSL 证书验证会使您面临 man/monster 中间攻击。它只会为那些被动拦截您的通信的人加密流量。获取可验证的商业证书,Let's encrypt 提供的免费证书,或明确信任所用 CA 的 self-signed 证书。
在评论中反复讨论后,您的 curl 似乎缺少其根 CA 包。该捆绑包用于验证所有 SSL 证书。从 libcurl 包中取出 curl-ca-bundle.crt
并将其放在您的程序旁边。您可能需要将 CURLOPT_CAINFO option 设置为指向该文件,然后 curl 才能将其用作证书包。
至于最后一个问题,这取决于你的威胁模型。 MitM 攻击允许以下所有行为:
- 你同意别人截取文件内容吗? (保密)
- 您的程序能否在对文件进行任意更改后存活下来? (文件损坏、重放攻击和可能的漏洞利用)
- 你的程序能承受任意大的文件吗? (DoS)
对于我的桌面软件 (Windows 7 - 10),我通过读取服务器上的文件检查版本并从中获取信息(读取 txt 文件)。这已经完成,但我不确定我是否使用正确的 SSL 设置以及是否需要为这个简单的事情提供安全性(我不确定 SSL 是如何工作的,我使用了 libcurl 示例中的一些示例)。我只读txt文件,获取信息(程序版本),仅此而已。
也许值得一提,我使用 libcurl 下载站点的二进制文件 Windows(二进制 curl 项目)。
这是我如何使用 libcurl 的部分代码:
std::stringstream isf;
CURL *curl;
CURLcode res;
/* CURL functions are function pointers because I load libcurl manually (LoadLibrary()) */
curl = curlEasyInit();
if (curl)
{
curlEasySetOpt(curl, CURLOPT_URL, "https://example.com/MyFile.txt");
curlEasySetOpt(curl, CURLOPT_WRITEFUNCTION, my_read_stream);
curlEasySetOpt(curl, CURLOPT_WRITEDATA, &isf);
// ------------------------------------------------------------------------------------------
// *** Question below ***
curlEasySetOpt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
curlEasySetOpt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // this is needed if I use CURLOPT_USE_SSL othervise it is unable to connect to https if I use CURLOPT_USE_SSL
// ------------------------------------------------------------------------------------------
res = curlEasyPerform(curl);
// ...
curlEasyCleanup(curl);
curlGlobalCleanup();
curl_easy_cleanup(curl);
}
size_t my_read_stream(void * buffer, size_t size, size_t nmemb, void * stream)
{
bool ok = false;
size_t b;
try {
std::stringstream * fs = static_cast<std::stringstream *>(stream);
b = size * nmemb;
fs->write(static_cast<char*>(buffer), b);
ok = true;
}
catch (std::exception e)
{
std::cout << "ERROR READ STREAM : " << e.what() << std::endl;
}
if (ok)
{
return b;
}
else
{
b = size * nmemb;
return b;
}
}
问题:
我能够连接 https://example.com/MyFile.txt
并在没有 SSL 设置的情况下读取文件(请参阅用注释封装的代码)。当我使用 curlEasySetOpt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL);
时,我无法连接到 https 站点,因为验证失败(需要一些认证),当我关闭 CURLOPT_SSL_VERIFYPEER
时,我可以连接到 https,现在的问题是:
- 此 SSL 设置(在我提供的代码中)是否足够安全以供读取 文件?
- 当我使用此 SSL 设置时,它会增加一些安全性吗?
- 当我使用时,这个简单的读取文件代码是否需要 SSL 安全性 https?
禁用 SSL 证书验证会使您面临 man/monster 中间攻击。它只会为那些被动拦截您的通信的人加密流量。获取可验证的商业证书,Let's encrypt 提供的免费证书,或明确信任所用 CA 的 self-signed 证书。
在评论中反复讨论后,您的 curl 似乎缺少其根 CA 包。该捆绑包用于验证所有 SSL 证书。从 libcurl 包中取出 curl-ca-bundle.crt
并将其放在您的程序旁边。您可能需要将 CURLOPT_CAINFO option 设置为指向该文件,然后 curl 才能将其用作证书包。
至于最后一个问题,这取决于你的威胁模型。 MitM 攻击允许以下所有行为:
- 你同意别人截取文件内容吗? (保密)
- 您的程序能否在对文件进行任意更改后存活下来? (文件损坏、重放攻击和可能的漏洞利用)
- 你的程序能承受任意大的文件吗? (DoS)