You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于libcurl与OpenSSL实现硬编码SSL证书白名单遇阻求助

问题分析与解决方案

你的问题核心是:代码仅将硬编码证书追加到信任存储,而非替换原有信任体系。即使清空了CAINFO和CAPATH,OpenSSL的SSL上下文仍可能保留默认信任的证书,导致任何合法CA签发的证书都能通过验证,最终出现"无论插什么证书都能连接"的情况。

方案1:公钥固定(推荐,更简洁可靠)

libcurl提供CURLOPT_PINNEDPUBLICKEY选项,直接硬编码服务器公钥的哈希值,仅匹配对应公钥的服务器,彻底阻断MITM攻击。

步骤:

  1. 提取服务器公钥的SHA256哈希:
    openssl s_client -connect your-server.com:443 < /dev/null | openssl x509 -pubkey -noout | openssl pkey -pubin -outform der | openssl dgst -sha256 -binary | base64
    
  2. 将哈希值硬编码到代码中:
    int main(void) {
        // ... 初始化curl等操作 ...
        // 替换为你的服务器公钥SHA256哈希
        const char* pinned_pubkey = "sha256/abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890";
        curl_easy_setopt(ch, CURLOPT_PINNEDPUBLICKEY, pinned_pubkey);
        curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 1L);
        // ... 执行请求 ...
    }
    

这种方法无需处理证书链,只要服务器公钥不变就持续有效,比硬编码证书更易维护。

方案2:严格只信任硬编码证书

如果坚持使用证书白名单,需修改sslctx_function,确保清空原有信任存储,仅添加目标证书:

修改后的回调函数:

static CURLcode sslctx_function(CURL *curl, void *sslctx, void *parm)
{
    CURLcode rv = CURLE_ABORTED_BY_CALLBACK;
    static const char my_server_cert[] =
        "-----BEGIN CERTIFICATE-----\n"
        // 替换为你的服务器证书完整内容
        "-----END CERTIFICATE-----\n";

    SSL_CTX *ctx = (SSL_CTX *)sslctx;
    X509_STORE *cts = SSL_CTX_get_cert_store(ctx);
    if (!cts) return rv;

    // 清空原有信任存储,确保无残留默认CA
    X509_STORE_cleanup(cts);

    // 从内存加载证书
    BIO *cbio = BIO_new_mem_buf(my_server_cert, sizeof(my_server_cert)-1); // 去掉字符串末尾的'\0'
    if (!cbio) return rv;

    X509 *cert = PEM_read_bio_X509(cbio, NULL, NULL, NULL);
    BIO_free(cbio);
    if (!cert) return rv;

    // 将证书添加到信任存储
    if (X509_STORE_add_cert(cts, cert) != 1) {
        X509_free(cert);
        return rv;
    }
    X509_free(cert);

    // 设置验证规则:仅验证服务器证书本身,不接受链上其他CA
    SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL);
    SSL_CTX_set_verify_depth(ctx, 1);

    rv = CURLE_OK;
    return rv;
}

主函数配套设置:

int main(void) {
    // ... 初始化curl ...
    curl_easy_setopt(ch, CURLOPT_SSL_VERIFYPEER, 1L);
    // 禁用默认CA路径
    curl_easy_setopt(ch, CURLOPT_CAINFO, NULL);
    curl_easy_setopt(ch, CURLOPT_CAPATH, NULL);
    // 设置自定义SSL上下文回调
    curl_easy_setopt(ch, CURLOPT_SSL_CTX_FUNCTION, sslctx_function);
    // ... 执行请求 ...
}

关键修改说明:

  • X509_STORE_cleanup(cts):清空原有信任存储,避免默认CA干扰
  • 直接加载单个服务器证书,设置验证深度为1,确保仅验证目标证书
  • 简化证书加载逻辑,避免原代码中证书链解析的冗余操作

内容的提问来源于stack exchange,提问作者caprisonne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 05:10:56