C语言中生成PEM格式RSA私钥函数出现段错误求助
问题排查与修复
核心错误分析
你的代码存在3个直接引发段错误的问题:
- 逻辑完全偏离需求:函数参数已经传入了
RSA *rsa,但你却调用PEM_read_bio_PrivateKey从keybio读取私钥,完全忽略了要处理的目标RSA对象,且未初始化的pkey直接传入&pkey,极易产生野指针。 - 无错误检查:
BIO_new_file可能因权限、路径问题返回NULL,后续调用PEM_write_bio_PrivateKey会直接访问空指针导致崩溃;PEM_read_bio_PrivateKey读取失败时,pkey也会成为无效指针。 - 资源未释放:打开的BIO和创建的EVP_PKEY没有释放,会造成内存泄漏。
修复后的代码
#include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/evp.h> void write_privatekey(RSA *rsa, const char *output_path) { if (!rsa) return; EVP_PKEY *pkey = EVP_PKEY_new(); if (!pkey) return; // 将传入的RSA对象关联到EVP_PKEY结构 if (EVP_PKEY_set1_RSA(pkey, rsa) != 1) { EVP_PKEY_free(pkey); return; } // 打开输出文件BIO,检查是否成功 BIO *bio_private = BIO_new_file(output_path, "w+"); if (!bio_private) { EVP_PKEY_free(pkey); return; } // 写入私钥到PEM文件 PEM_write_bio_PrivateKey(bio_private, pkey, NULL, NULL, 0, NULL, NULL); // 释放所有资源 BIO_free(bio_private); EVP_PKEY_free(pkey); }
关键修复说明
- 复用传入的RSA对象:通过
EVP_PKEY_set1_RSA将目标RSA对象封装到EVP_PKEY中,符合OpenSSL的密钥操作规范。 - 添加完整错误拦截:对所有可能返回NULL的操作做判断,避免空指针访问。
- 资源及时释放:确保BIO和EVP_PKEY在函数结束前被释放,避免内存泄漏。
- 灵活参数设计:将输出文件路径作为参数传入,替代硬编码的文件名,提升函数通用性。
调用示例
假设你已有一个有效初始化的RSA对象rsa,调用方式如下:
write_privatekey(rsa, "private_new.pem");
内容的提问来源于stack exchange,提问作者Poutite
相关产品推荐
相关产品推荐

