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

使用OpenSSL在C语言中从PEM格式证书链文件中提取单个证书

从PEM格式证书链中逐个提取证书的实现方法

嘿,既然你已经搞定了PKCS#12文件的证书提取,那处理PEM格式的证书链其实更直接——OpenSSL提供了专门的PEM读取函数,可以循环读取链中的每一个X509证书,和你处理PKCS#12的逻辑能很好地对应上。

核心思路

PEM格式的证书链本质是多个独立的PEM证书拼接而成,每个证书都以-----BEGIN CERTIFICATE-----开头、-----END CERTIFICATE-----结尾。我们可以用PEM_read_X509函数循环读取文件,直到没有更多证书为止,读取到的每个证书都可以像你处理PKCS#12提取出的证书一样操作(比如转DER格式、存入证书栈等)。

完整代码示例

下面是和你之前PKCS#12代码风格一致的实现:

#include <stdio.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/err.h>

int main() {
    FILE *pem_file;
    STACK_OF(X509) *cert_chain = sk_X509_new_null(); // 创建存储证书的栈,和你用的additional_certs结构一致
    X509 *single_cert = NULL;

    // 打开PEM证书链文件(PEM是ASCII格式,用文本模式r即可)
    pem_file = fopen("/etc/certs/chain.pem", "r");
    if (!pem_file) {
        perror("Failed to open PEM certificate chain file");
        return -1;
    }

    // 循环读取每个证书,直到文件结束
    while ((single_cert = PEM_read_X509(pem_file, NULL, NULL, NULL)) != NULL) {
        // 将证书存入栈中,方便后续批量处理
        sk_X509_push(cert_chain, single_cert);

        // 这里可以直接处理当前证书,比如转换成DER格式(和你之前i2d_X509的用法完全一样)
        unsigned char *der_cert = NULL;
        int der_len = i2d_X509(single_cert, &der_cert);
        if (der_len > 0) {
            // 示例:打印DER数据长度,你可以换成保存到文件等操作
            printf("Extracted certificate DER length: %d\n", der_len);
            OPENSSL_free(der_cert); // 务必释放i2d_X509分配的内存
        } else {
            fprintf(stderr, "Failed to convert certificate to DER\n");
            ERR_print_errors_fp(stderr); // 打印OpenSSL错误信息便于排查
        }
    }

    fclose(pem_file);

    // 遍历证书栈,和你处理PKCS#12的additional_certs逻辑一致
    int cert_count = sk_X509_num(cert_chain);
    printf("Total extracted certificates: %d\n", cert_count);
    for (int i = 0; i < cert_count; i++) {
        X509 *cert = sk_X509_value(cert_chain, i);
        // 这里可以对每个证书执行你需要的操作,比如获取证书主题、有效期等
        // ...
    }

    // 释放所有资源:sk_X509_pop_free会自动释放栈内的所有X509对象
    sk_X509_pop_free(cert_chain, X509_free);
    ERR_free_strings();

    return 0;
}

关键细节说明

  1. 证书读取函数:PEM_read_X509会自动识别文件中的PEM格式证书,跳过无关内容(如果有的话),每次调用返回一个X509*对象,直到返回NULL表示没有更多证书。
  2. 内存管理:
    • 用sk_X509_new_null()创建证书栈,和你处理PKCS#12时的additional_certs结构完全兼容,遍历方式也一样。
    • sk_X509_pop_free是释放证书栈的最佳方式,它会一次性释放栈本身以及栈内所有的X509对象,避免内存泄漏。
    • i2d_X509分配的内存必须用OPENSSL_free释放,不能用普通的free。
  3. 错误排查:如果读取或转换证书失败,可以用ERR_print_errors_fp(stderr)打印OpenSSL的详细错误信息,帮助定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 19:07:33