C++使用libcurl发起SSL请求时如何将CA证书/私钥内置到项目中
可行解决方案
你当前使用的libcurl本身就内置了直接读取内存中证书、私钥的能力,不需要额外引入第三方库,即可实现证书、私钥内置到二进制包中,无需用户额外配置文件。
具体实现步骤
步骤1:将证书、私钥内容转为代码内字符串常量
直接将你的ca.pem和key.pem的文本内容,通过C++11及以上支持的原始字符串字面量存入代码:
// 内置CA证书内容,直接粘贴ca.pem的全部内容到引号内 const char* BUILTIN_CA = R"( -----BEGIN CERTIFICATE----- MIIFazCCA1OgAwIBAgI... 你的CA证书实际内容 -----END CERTIFICATE----- )"; // 内置客户端私钥内容,直接粘贴key.pem的全部内容到引号内 const char* BUILTIN_PRIVATE_KEY = R"( -----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhki... 你的私钥实际内容 -----END PRIVATE KEY----- )";
如果你的私钥设置了访问密码,额外加一行常量存储密码即可。
步骤2:修改libcurl配置,替换文件路径为内存数据
你原来使用的CURLOPT_CAINFO、CURLOPT_SSLKEY都是读取磁盘文件的配置项,替换为对应内存读取的配置项即可,修改后的核心代码如下:
std::string do_request( std::string type, std::string post_data ) { CURL* c_url = curl_easy_init( ); if ( !c_url ) return _( "null" ); std::string to_return; curl_easy_setopt( c_url, CURLOPT_URL, std::string( api_endpoint + type + post_data ).c_str( ) ); curl_easy_setopt( c_url, CURLOPT_USERAGENT, user_agent.c_str( ) ); curl_easy_setopt( c_url, CURLOPT_NOPROXY, api_endpoint ); // 新增:构造curl blob结构存储内存中的证书、私钥数据 struct curl_blob ca_blob { .data = (void*)BUILTIN_CA, .len = strlen(BUILTIN_CA), .flags = CURL_BLOB_COPY }; struct curl_blob key_blob { .data = (void*)BUILTIN_PRIVATE_KEY, .len = strlen(BUILTIN_PRIVATE_KEY), .flags = CURL_BLOB_COPY }; curl_easy_setopt( c_url, CURLOPT_SSLKEYTYPE, _( "PEM" ) ); // 替换原CURLOPT_SSLKEY为CURLOPT_SSLKEY_BLOB curl_easy_setopt( c_url, CURLOPT_SSLKEY_BLOB, &key_blob ); // 替换原CURLOPT_CAINFO为CURLOPT_CAINFO_BLOB curl_easy_setopt( c_url, CURLOPT_CAINFO_BLOB, &ca_blob ); // 私钥有密码的话加这一行 // curl_easy_setopt( c_url, CURLOPT_KEYPASSWD, _("你的私钥密码") ); curl_easy_setopt( c_url, CURLOPT_SSL_VERIFYPEER, 1L ); curl_easy_setopt( c_url, CURLOPT_SSL_VERIFYHOST, 1L ); curl_easy_setopt( c_url, CURLOPT_WRITEFUNCTION, write_callback ); curl_easy_setopt( c_url, CURLOPT_WRITEDATA, &to_return ); auto code = curl_easy_perform( c_url ); return to_return; }
版本兼容说明
CURLOPT_SSLKEY_BLOB需要libcurl 7.71.0及以上版本CURLOPT_CAINFO_BLOB需要libcurl 7.77.0及以上版本
如果你使用的libcurl版本低于上述要求,可以用临时文件兼容方案:- 程序启动时将内置的证书、私钥内容写入系统临时目录的隐藏临时文件
- 还是用原有的
CURLOPT_CAINFO、CURLOPT_SSLKEY指向临时文件路径 - 程序退出时自动删除临时文件即可,不需要额外依赖库。
安全提示:将私钥内置到二进制文件存在被逆向提取的风险,高安全级别的业务建议还是给每个用户分发独立的专属证书私钥,内置方案仅适用于非高敏感的通用场景。
内容的提问来源于stack exchange,提问作者Halogen
相关产品推荐
相关产品推荐

