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

如何在C++中打开带密码的PEM私钥文件并转为std::string

在C++中读取带密码的PEM私钥并转为std::string

你已经通过PEM_read_PrivateKey成功读取了加密私钥到EVP_PKEY对象中,要把这个密钥转换成PEM格式的std::string,需要借助OpenSSL的内存BIO缓冲区实现——因为OpenSSL没有直接将EVP_PKEY转字符串的接口,得通过中间载体过渡。

完整实现代码

#include <string>
#include <openssl/pem.h>
#include <openssl/evp.h>

auto read_file(const std::string& private_key_path) -> std::string {
    const std::string keypass = "pass";
    FILE* fp = fopen(private_key_path.c_str(), "r");
    if (!fp) {
        return ""; // 可根据需求替换为异常抛出等错误处理逻辑
    }

    // 读取加密私钥
    EVP_PKEY* pkey = PEM_read_PrivateKey(fp, NULL, NULL, const_cast<char*>(keypass.c_str()));
    fclose(fp); // 文件读取完成后及时关闭
    if (!pkey) {
        return ""; // 私钥读取失败,返回空或处理错误
    }

    // 创建内存BIO作为PEM内容的临时存储
    BIO* bio = BIO_new(BIO_s_mem());
    if (!bio) {
        EVP_PKEY_free(pkey);
        return "";
    }

    // 将私钥写入BIO:这里选择输出加密的PEM(和原文件一致),若要明文输出,把加密算法设为NULL,密码参数也传NULL
    int ret = PEM_write_bio_PrivateKey(bio, pkey, EVP_aes_256_cbc(), 
                                      const_cast<char*>(keypass.c_str()), keypass.size(),
                                      NULL, NULL);
    if (!ret) {
        BIO_free(bio);
        EVP_PKEY_free(pkey);
        return "";
    }

    // 从BIO中读取数据到std::string
    char* buf = nullptr;
    long len = BIO_get_mem_data(bio, &buf);
    std::string private_key(buf, len);

    // 释放所有OpenSSL资源,避免内存泄漏
    BIO_free(bio);
    EVP_PKEY_free(pkey);

    return private_key;
}

关键细节说明

  • 内存BIO的作用:BIO_s_mem()创建的内存缓冲区可以让我们在内存中生成PEM内容,无需写入磁盘文件
  • 加密控制:PEM_write_bio_PrivateKey的第三个参数指定加密算法(示例用AES-256-CBC和原文件保持一致),如果不需要加密输出,直接将加密算法设为NULL,同时密码相关参数也传NULL即可
  • 错误处理:添加了文件打开、私钥读取、BIO创建、写入失败的判断,避免程序崩溃
  • 资源释放:所有OpenSSL创建的对象(EVP_PKEY、BIO)必须手动调用对应_free函数释放,文件指针也要及时关闭

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 05:05:19