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
相关产品推荐
相关产品推荐

