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

C语言调用OpenSSL修改X509证书扩展后更改未生效如何解决

代码错误点及修复方案

核心错误点

  • 操作了不可修改的const证书对象:你调用parse_certificate返回的是const X509 *cert,const修饰的对象本身就是禁止修改的,你所有删除扩展、添加SCT的操作都作用在了这个只读对象上,修改行为未定义,实际上根本不会生效。你代码中X509_cmp( cert, certRef)已经返回0并打印FAILED!!! ,就是修改未生效的明确信号。
  • 错误操作只读扩展栈:X509_get0_extensions返回的是X509内部的const STACK_OF(X509_EXTENSION),属于只读的内部引用,你直接对它调用X509v3_delete_ext属于非法操作,不会修改X509对象本身的扩展列表。正确的做法是直接使用X509对象的修改接口:用X509_get_ext_by_NID查找扩展索引,再用X509_delete_ext删除对应位置的扩展。
  • 输出的证书对象错误:你最后调用PEM_write_bio_X509输出的是原始的只读cert对象,而不是你修改后的对象,自然输出的内容和原始证书完全一致。
  • 验证逻辑错误:你最后验证poison扩展是否存在时,直接把X509_get_ext_by_NID的返回值(如果扩展已删除会返回-1)传入X509_get_ext,会必然返回空指针,导致你误以为操作失败,实际这是验证逻辑写反了:如果my_idx2 == -1才代表poison扩展已经被成功删除。

核心修复代码示例

// 1. 操作dup出来的非const对象certRef,不要操作原始只读cert
int poison_idx;
while ((poison_idx = X509_get_ext_by_NID(certRef, NID_ct_precert_poison, -1)) != -1) {
    X509_EXTENSION *ext = X509_delete_ext(certRef, poison_idx);
    X509_EXTENSION_free(ext);
    printf("删除一个poison扩展,索引:%d\n", poison_idx);
}

// 2. 把SCT扩展添加到修改后的certRef上
if( X509_add_ext(certRef, extSCT, -1)) {
    printf("Extension added\n");
    X509_EXTENSION_free(extSCT);
}

// 3. 输出修改后的certRef,不是原始cert
PEM_write_bio_X509(Cout, certRef);

// 4. 正确验证poison扩展是否删除
int my_idx2 = X509_get_ext_by_NID(certRef, NID_ct_precert_poison, -1);
if (my_idx2 == -1) {
    printf("poison扩展已成功删除\n");
} else {
    printf("poison扩展仍存在,索引:%d\n", my_idx2);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 22:00:00