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

OpenSSL v1.1.0f设置RSA密钥时出现「不完整类型」错误求助

解决OpenSSL 1.1.0f中RSA结构体“dereferencing pointer to incomplete type”错误

这个问题我之前适配OpenSSL 1.1.x版本时也碰到过,根源很明确:OpenSSL从1.1.0版本开始,将RSA、EVP等核心结构体改成了不透明类型(opaque type),目的是提升API的封装性和向后兼容性,你不能再像旧版本那样直接通过keys->n、keys->e这种方式访问结构体内部成员了,这就是你触发错误的原因。

下面是具体的解决步骤和代码示例:

1. 使用OpenSSL提供的专用函数设置密钥参数

OpenSSL 1.1.0+提供了一系列替代直接访问结构体的API,用来设置RSA的公/私钥参数:

  • 设置公钥(n、e):使用RSA_set0_key()或RSA_set0_pubkey()
  • 设置私钥因子(p、q):使用RSA_set0_factors()
  • 设置私钥CRT参数:使用RSA_set0_crt_params()

以你的加密函数为例,修改后的正确代码如下:

#include <openssl/rsa.h>
#include <openssl/bn.h>

// 假设byte是你定义的unsigned char别名
int rsa_encrypt(byte *in, size_t in_len, byte *out, const char *n_hex, const char *e_hex, char padding){
    int err = -1;
    RSA *keys = RSA_new();
    if (!keys) {
        return err;
    }

    BIGNUM *n = NULL, *e = NULL;
    // 将十六进制字符串转换为BIGNUM
    if (!BN_hex2bn(&n, n_hex) || !BN_hex2bn(&e, e_hex)) {
        BN_free(n);
        BN_free(e);
        RSA_free(keys);
        return err;
    }

    // 使用RSA_set0_key设置公钥参数:最后一个参数d传NULL(公钥不需要私钥指数)
    if (!RSA_set0_key(keys, n, e, NULL)) {
        // 如果设置失败,需要手动释放BIGNUM
        BN_free(n);
        BN_free(e);
        RSA_free(keys);
        return err;
    }
    // 注意:调用RSA_set0_key后,OpenSSL会接管n和e的内存,后续不需要手动free

    // 处理填充模式
    int pad_mode;
    switch(padding){
        case 'o':
            pad_mode = RSA_PKCS1_OAEP_PADDING;
            break;
        case 'p':
            pad_mode = RSA_PKCS1_PADDING;
            break;
        default:
            pad_mode = RSA_NO_PADDING;
            break;
    }

    // 执行公钥加密
    int out_len = RSA_public_encrypt((int)in_len, in, out, keys, pad_mode);
    if (out_len > 0) {
        err = 0;
    }

    // 只需要释放RSA结构体,内部的BIGNUM会被自动清理
    RSA_free(keys);
    return err;
}

2. 确认编译和链接配置

确保你的代码包含了正确的头文件#include <openssl/rsa.h>,并且编译时链接OpenSSL的crypto库,比如使用GCC编译时加上参数:

gcc your_code.c -o your_program -lcrypto

额外注意事项

  • 如果需要设置私钥的p、q、d等参数,同样要用对应的RSA_set0_*函数,比如RSA_set0_factors(keys, p, q)来设置素因子p和q。
  • 所有通过BN_hex2bn创建的BIGNUM,一旦通过RSA_set0_*传递给RSA结构体,就不需要手动调用BN_free了,RSA_free会自动清理这些内存,避免内存泄漏。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:21:52