Windows平台C++获取SSL证书过期日期的实现方法咨询
C++获取SSL证书过期日期简易实现
你之前遇到的不同终端下curl命令输出不一致的问题,本质是Windows cmd环境下调用的curl版本和Git Bash自带的curl版本编译配置不同,靠解析外部命令输出拿证书信息本身兼容性很差,不建议实际使用。
既然你项目里已经在用libcpr,它底层就是基于libcurl封装的,你不需要额外引入重型依赖,直接调用libcurl原生接口搭配它默认依赖的OpenSSL就能拿到证书过期时间,代码量很小,适合初学者。
实现步骤
- 初始化curl_easy句柄,配置目标请求地址
- 开启证书信息收集选项,完成SSL握手后curl会自动把服务端返回的证书链存在内存里
- 取出服务端对应的叶子证书,用OpenSSL接口解析过期时间字段
- 计算剩余有效期、格式化输出即可
可直接运行的示例代码
// 编译说明:如果是用vcpkg/conan安装的libcpr,不需要额外配置链接库 // 手动编译时需追加链接参数:-lcurl -lssl -lcrypto #include <iostream> #include <ctime> #include <curl/curl.h> #include <openssl/x509.h> #include <openssl/pem.h> #include <openssl/bio.h> int main() { CURL* curl = curl_easy_init(); if (!curl) { std::cerr << "curl初始化失败" << std::endl; return 1; } // 基础请求配置,替换为你要查询的目标域名 curl_easy_setopt(curl, CURLOPT_URL, "https://www.example.com"); curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); // 仅做握手不下载页面内容,提升速度 curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); // 自动跟随3xx跳转 curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L); // 开启证书信息收集 // 对应你之前curl命令的--insecure参数,正式环境请删除这两行,开启证书校验 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); // 发起连接完成SSL握手 CURLcode res = curl_easy_perform(curl); if (res != CURLE_OK) { std::cerr << "连接失败: " << curl_easy_strerror(res) << std::endl; curl_easy_cleanup(curl); return 1; } // 读取证书链信息 struct curl_certinfo* ci = nullptr; curl_easy_getinfo(curl, CURLINFO_CERTINFO, &ci); if (!ci || ci->num_of_certs == 0) { std::cerr << "未获取到有效证书信息" << std::endl; curl_easy_cleanup(curl); return 1; } // 解析第一个证书(即服务端当前使用的叶子证书) BIO* bio = BIO_new_mem_buf(ci->certinfo[0].cert, -1); X509* server_cert = PEM_read_bio_X509(bio, nullptr, nullptr, nullptr); BIO_free(bio); if (!server_cert) { std::cerr << "证书解析失败" << std::endl; curl_easy_cleanup(curl); return 1; } // 提取证书过期时间 ASN1_TIME* expire_asn1 = X509_get_notAfter(server_cert); struct tm expire_tm = {0}; ASN1_TIME_to_tm(expire_asn1, &expire_tm); time_t expire_ts = mktime(&expire_tm); time_t now_ts = time(nullptr); int remain_days = static_cast<int>((expire_ts - now_ts) / 86400); // 输出结果 std::cout << "证书过期时间(GMT): " << asctime(&expire_tm); std::cout << "距离过期剩余天数: " << remain_days << " 天" << std::endl; // 释放资源 X509_free(server_cert); curl_easy_cleanup(curl); return 0; }
注意事项
- 这个方案不依赖任何外部命令,在Windows、Linux、macOS下运行逻辑完全一致,不会出现不同终端输出格式不兼容的问题
- 如果你不想引入OpenSSL的接口调用,也可以直接遍历
ci->certinfo[0].cert里的PEM文本,搜索过期时间字段做字符串截取,但用OpenSSL原生接口解析稳定性更高,不会因为curl版本迭代调整输出格式导致解析失败 - 正式环境使用务必打开证书校验开关,避免连接到伪造的服务端拿到错误的证书信息
内容的提问来源于stack exchange,提问作者Anees
相关产品推荐
相关产品推荐

