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

OpenSSL 3中从RSA密钥对提取编码公钥失败问题排查

问题:RSA密钥对生成成功,但无法用EVP_PKEY_get1_encoded_public_key提取公钥

我尝试通过以下代码生成RSA密钥对并提取公钥,密钥生成过程经输出验证是成功的。根据OpenSSL手册说明,调用EVP_PKEY_get1_encoded_public_key的方式看似正确,但该函数始终无法提取公钥,恳请指出我的代码错误之处。

#include <openssl/bn.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <stdio.h>

void print_hex(const char *label, const unsigned char *data, size_t length) {
  printf("%s:\n", label);
  for (size_t i = 0; i < length; ++i) {
    printf("%02X", data[i]);
  }
  printf("\n");
}

int main() {

  // Generate RSA key pair
  EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
  if (!ctx) {
    printf("Failed to create EVP_PKEY_CTX.\n");
    return 1;
  }

  if (EVP_PKEY_keygen_init(ctx) <= 0) {
    printf("Failed to initialize EVP_PKEY_CTX.\n");
    return 1;
  }

  if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 2048) <= 0) {
    printf("Failed to set RSA key size.\n");
    return 1;
  }

  EVP_PKEY *keypair = NULL;
  if (EVP_PKEY_keygen(ctx, &keypair) <= 0) {
    printf("Failed to generate RSA key pair.\n");
    return 1;
  }

  // Extract RSA public key modulus
  unsigned char *pubkey;
  size_t pubkey_len;

  pubkey_len = EVP_PKEY_get1_encoded_public_key(keypair, &pubkey);

  if (pubkey_len == 0) {
    printf("Failed to get encoded public key length.\n");
    EVP_PKEY_CTX_free(ctx);
    EVP_PKEY_free(keypair);
    return 1;
  }

  // Print the raw key component
  print_hex("Encoded Public Key", pubkey, pubkey_len);

  // Cleanup
  free(pubkey);
  EVP_PKEY_CTX_free(ctx);
  EVP_PKEY_free(keypair);

  return 0;
}
错误分析与修复方案
  • 缺失OpenSSL错误信息打印:你的错误处理仅输出自定义提示,没有打印OpenSSL底层的错误详情,这会导致无法定位EVP_PKEY_get1_encoded_public_key失败的具体原因。在pubkey_len == 0的分支中,添加ERR_print_errors_fp(stderr);可以直接获取OpenSSL的错误栈信息,比如算法支持问题、密钥格式不兼容等。

  • 内存释放方式错误:EVP_PKEY_get1_encoded_public_key通过OpenSSL的内存分配器分配内存,必须使用OPENSSL_free(pubkey)释放,而非标准库的free。两者分配器不兼容,误用会导致内存泄漏、程序崩溃,甚至可能干扰函数的正常执行逻辑。

  • 可选验证方案:如果仍无法解决,可以尝试先将EVP_PKEY转换为RSA结构来提取公钥,作为替代验证方式:

    RSA *rsa = EVP_PKEY_get1_RSA(keypair);
    if (rsa == NULL) {
        ERR_print_errors_fp(stderr);
        return 1;
    }
    // 提取PEM格式公钥示例
    FILE *fp = fopen("pubkey.pem", "w");
    PEM_write_RSA_PUBKEY(fp, rsa);
    fclose(fp);
    RSA_free(rsa);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 14:10:31