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

OpenSSL 1.1.1升级至3.0.5后i2d_X509_REQ返回-1的兼容问题求助

问题解决:OpenSSL 3.0.5中i2d_X509_REQ返回-1的兼容性问题及错误排查方法

一、先解决错误原因打印问题

要定位OpenSSL接口调用失败的具体原因,仅靠返回的错误码无法获取有效信息,需要打印OpenSSL的错误栈。按以下步骤实现:

  1. 新增错误处理头文件引用:
#include <openssl/err.h>
  1. 实现错误打印函数:
void print_openssl_errors() {
    ERR_print_errors_fp(stderr); // 将错误信息输出到标准错误流
    ERR_clear_error(); // 清空错误栈,避免干扰后续错误判断
}
  1. 在i2d_X509_REQ调用失败后触发打印:
int length = i2d_X509_REQ(CR, NULL);
if (length <= 0) {
    std::cout << "i2d_X509_REQ fail " << length << std::endl;
    print_openssl_errors(); // 输出具体错误原因
}

调用后会看到类似X509_REQ not signed的明确错误信息,这是定位问题的核心依据。

二、i2d_X509_REQ返回-1的根本原因及修复

你的代码创建了X509_REQ对象并设置了主题名称、公钥,但缺少对证书请求的签名步骤。OpenSSL 3.0版本对X.509结构的有效性检查大幅收紧,未签名的证书请求属于无效结构,无法被正确编码;而OpenSSL 1.1.1对未签名请求的编码限制更宽松,这是兼容性差异的关键。

修复步骤:

在X509_REQ_set_pubkey之后添加签名逻辑,使用生成的私钥对证书请求进行签名:

// 用SHA256摘要算法对证书请求签名
if (X509_REQ_sign(CR, pkey, EVP_sha256()) <= 0) {
    std::cout << "X509_REQ_sign failed" << std::endl;
    print_openssl_errors();
}

完成签名后,再调用i2d_X509_REQ(CR, NULL)即可正常获取证书请求的DER编码长度。

三、修复后的关键代码片段

// ... 原有代码 ...

if(1 == X509_REQ_set_pubkey(CR, pkey)) {
    std::cout << "X509_REQ_set_pubkey success" << std::endl;
}

// 新增:对证书请求进行签名
if (X509_REQ_sign(CR, pkey, EVP_sha256()) <= 0) {
    std::cout << "X509_REQ_sign failed" << std::endl;
    print_openssl_errors();
}

int length = i2d_X509_REQ(CR, NULL);
if (length <= 0) {
    std::cout << "i2d_X509_REQ fail " << length << std::endl;
    print_openssl_errors();
} else {
    std::cout << "i2d_X509_REQ success, length: " << length << std::endl;
}

// ... 后续资源清理代码 ...

四、额外注意事项

  • OpenSSL 3.0对所有X.509相关结构的合规性要求更高,必填字段缺失、未签名等情况都会导致编码失败。
  • 操作完成后记得释放资源:X509_REQ_free(CR);、EVP_PKEY_free(pkey);,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 21:40:37