【问题标题】:C/C++ Validating Host and Peer with CURL for CloudFlare based websitesC/C++ 使用 CURL 验证基于 CloudFlare 的网站的主机和对等体
【发布时间】:2021-12-11 14:46:46
【问题描述】:

我正在开发 CloudFlare 背后的 API,我想完全验证连接以扩展安全性。我现在使用的平台是 Windows 10。

首先我下载了​​一些在 CloudFlare 网站上找到的 CA(Cloudflare_CA.pemorigin_ca_rsa_root.pemorigin_ca_ecc_root.pem),然后尝试在 CURL 中设置好所需的选项后联系 API:

struct curl_blob blob;

std::string cf_pem = ...;

blob.data   = cf_pem.data();
blob.len    = cf_pem.size();
blob.flags  = CURL_BLOB_COPY;
curl_easy_setopt(pcurl, CURLOPT_CAINFO_BLOB, &blob);

/* Set the default value: strict certificate check please */
curl_easy_setopt(pcurl, CURLOPT_SSL_VERIFYPEER, 1L);

/* Set the default value: strict name check please */
curl_easy_setopt(pcurl, CURLOPT_SSL_VERIFYHOST, 2L);

全部失败,出现 PEER 验证错误。然后我用openssl测试了以下内容:

openssl s_client -connect website:443

结果是:

New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 256 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 20 (unable to get local issuer certificate)

后来我发现了一个非常好的命令,它基本上从给定的网站“提取”了 CA:

openssl s_client -showcerts -servername website -connect website:443 > cacert.pem

最后我还是收到了:

Verify return code: 20 (unable to get local issuer certificate)

但是,cacert.pem 是在其中创建了一些内容。我在 -----BEGIN CERTIFICATE-----/-----END CERTIFICATE----- 之间获取了第一个证书,并将其放入代码中。

验证成功,CURL 不再抱怨。但是,我无法联系 CloudFlare 下的其他主机,这意味着此 CA 不“正常”。

所以我的问题是,该怎么办?如何为 CloudFlare 找到正确的 CA?

请指教,我相信其他开发者也可能面临同样的问题。

【问题讨论】:

    标签: c++ c windows ssl curl


    【解决方案1】:

    正如@David 提到的,CloudFlare 使用 DigiCert Root CA(通常)是正确的。但是,正如他们在their website 上所说的那样,这可能会改变;这意味着如果您对此类检查进行硬编码,您的软件可能会在将来的任何时候中断。

    无需进一步说明,选项如下:

    选项 A

    从 CloudFlare 购买“高级”证书而不是通用证书,然后选择所需的根 CA。这确保(在一定程度上)它是相同的,并且您可以使用该 CA 验证任何域(在我的情况下,我使用 DigiCert Root CA 进行了测试)。

    选项 B

    使用 mTLS 功能(mTLS 是保护您的 API 的好方法)。作为长期解决方案,这是首选,但缺点是您需要在软件中提供/嵌入证书私钥。但是,如果证书被泄露,您可以随时撤销证书。

    对于我的选择,我还想验证 CA,但是使用 DigiCert 根 CA 不适用于 mTLS,这很清楚,因为在您的仪表板上您会看到:

    Review Client Certificate for CN=Cloudflare, C=US
    Validity Period: 15 Years
    Authority: Cloudflare Managed CA for ....
    

    我找不到/下载“Cloudflare 托管 CA”的根证书。我对此不满意,所以为了确保一切正常,我从这里使用了“Baltimore Cyber​​Trust Root”:https://baltimore-cybertrust-root.chain-demos.digicert.com/info/index.html

    现在您也可以使用带有 CA 验证的 CURL 的 mTLS:

    // https://baltimore-cybertrust-root.chain-demos.digicert.com/info/index.html
    std::string ca_pem = ...
    
    // mtls.cert
    std::string cert = ...
    
    // mtls.key
    std::string key = ...
    
    struct curl_blob blob;
    blob.data   = cert.data();
    blob.len    = cert.size();
    blob.flags  = CURL_BLOB_COPY;
    curl_easy_setopt(pcurl, CURLOPT_SSLCERT_BLOB, &blob);
    curl_easy_setopt(pcurl, CURLOPT_SSLCERTTYPE, "PEM");
    
    blob.data   = key.data();
    blob.len    = key.size();
    curl_easy_setopt(pcurl, CURLOPT_SSLKEY_BLOB, &blob);
    curl_easy_setopt(pcurl, CURLOPT_SSLKEYTYPE, "PEM");
    
    blob.data   = ca_pem.data();
    blob.len    = ca_pem.size();
    curl_easy_setopt(pcurl, CURLOPT_CAINFO_BLOB, &blob);
    

    关于 mTLS 的重要说明:

    • 如果您嵌入证书/密钥,请确保您努力加密您的证书/密钥 在您的软件中。
    • 我不建议您将证书/密钥作为个人文件提供 在您的软件旁边。
    • 即使您在软件中加密了证书/密钥,也存在 总是通过解包/去混淆/去虚拟化来获得它;任何一个 在运行时...等等。我的建议是立即重新加密 数据或尽快从内存中删除
    • 万一有人得到你的证书/密钥,首先生成一个新的证书/密钥 然后更新您的软件,然后撤销现有软件。 然后你应该看看有人如何得到你的证书/密钥并尝试 缓解问题。

    如果您有任何不同意和/或/如果您有一些建议/改进,请随时发表评论。

    【讨论】:

      【解决方案2】:

      查看一个典型的 Cloudflare 托管站点,认证路径以“DigiCert Baltimore Root”的根 CA 结束。

      在 Windows 10 中,应该能够在 Local Machine Certs -> Trusted Root Certification Authority -> Certificates -> Baltimore Cyber​​Trust Root 下找到此证书。

      或者,从源下载(如果您使用此方法可能还需要验证指纹)-https://www.digicert.com/kb/digicert-root-certificates.htm

      【讨论】:

      • 看来你是对的,但这意味着 CloudFlare 是从其他人那里购买证书。这也意味着这可能会因您的域而改变,如果您对例如 DigiCert CA 根目录进行硬编码,它可能会破坏您的软件。
      猜你喜欢
      • 2021-11-08
      • 2021-07-24
      • 1970-01-01
      • 2017-09-04
      • 2012-08-06
      • 1970-01-01
      • 1970-01-01
      • 2019-02-01
      • 2011-01-03
      相关资源
      最近更新 更多