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

如何检查X509根证书是否在系统可信证书库中(C语言OpenSSL实现)

手动验证OpenSSL证书链中的根证书

要拒绝untrusted-root.badssl.com或self-signed.badssl.com这类无效证书,核心是确认链中最后一个证书是系统可信库中被认可的根证书,而不是仅检查签名或信任标志。以下是具体实现步骤和代码:

核心思路

  1. 在系统可信库中查找与待验证根证书匹配的条目(不能直接内存比较,需通过主体名称/密钥哈希匹配)。
  2. 验证该可信证书是否被允许用于TLS服务器认证(或对应场景的用途)。
  3. 确认根证书是合法自签的(可信根必须自签)。

实现代码

X509* cert; // 证书链的最后一个证书(待验证的根证书)
X509_STORE* store = SSL_CTX_get_cert_store(ctx); // 系统可信证书库

// 1. 在可信库中查找匹配的根证书
X509_LOOKUP* lookup = X509_STORE_get_lookup(store);
if (lookup == NULL) {
    fprintf(stderr, "Failed to get lookup from trusted store\n");
    return -1;
}

X509_NAME* subject_name = X509_get_subject_name(cert);
X509* trusted_root = X509_LOOKUP_find(lookup, X509_LOOKUP_BY_SUBJECT_NAME, subject_name);

if (trusted_root == NULL) {
    // 根证书不在可信库中,直接拒绝
    fprintf(stderr, "Root certificate not found in trusted store\n");
    return -1;
}

// 2. 验证该证书是否被信任用于TLS服务器认证
int trust_status = X509_check_trust(trusted_root, X509_TRUST_TLS_SERVER, NULL);
if (trust_status != X509_V_OK) {
    fprintf(stderr, "Root certificate is not trusted for TLS server auth\n");
    X509_free(trusted_root);
    return -1;
}

// 3. 确认根证书是合法自签的(可信根必须满足)
if (!X509_self_signed(trusted_root)) {
    fprintf(stderr, "Trusted root certificate is not self-signed\n");
    X509_free(trusted_root);
    return -1;
}

// 所有验证通过
X509_free(trusted_root);
return 0;

关键细节说明

  • 可信库查找:使用X509_LOOKUP_find而非直接内存比较,因为系统可信库中的证书可能存在编码、扩展差异,但主体名称/密钥标识是一致的,查找函数会自动匹配对应条目。
  • 信任用途检查:X509_check_trust的X509_TRUST_TLS_SERVER参数限定证书用途为TLS服务器认证,能排除那些可信但不适用于该场景的证书(比如仅用于代码签名的根证书)。
  • 自签检查:X509_self_signed仅验证签名有效性,不能替代可信库检查——self-signed.badssl.com的证书是自签且签名有效,但不在可信库中,所以必须结合前面的查找步骤。

为什么之前的方法无效

  • X509_trusted:仅检查证书的内部TRUSTED标志,需要手动标记证书为可信,而非从系统库中查找,因此无法识别系统不认可的根证书。
  • X509_self_signed:只验证签名逻辑,不关心证书是否在可信库中,所以无法区分合法自签根和恶意自签证书。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:37:28