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

OpenSSL中PEM_read_PUBKEY返回NULL问题排查求助

PEM_read_PUBKEY加载RSA公钥失败的原因分析

问题场景

尝试加载PEM格式的RSA公钥用于加密,但PEM_read_PUBKEY始终返回NULL,使用的代码如下:

QString publicKeyFilePath = QString(FILE_PATH);
if (!QFile::exists(publicKeyFilePath))
{
    std::cout << "Doesn't exist." << std::endl;
}

FILE *publicKeyFile = fopen(publicKeyFilePath.toStdString().c_str(), "rb");
EVP_PKEY *publicKey = PEM_read_PUBKEY(publicKeyFile, NULL, NULL, NULL);
if (publicKey == nullptr)
{
    std::cout << "PEM_read_PUBKEY failed." << std::endl;
}
fclose(publicKeyFile);

对应的公钥文件内容为:

-----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAonmLnagQuiepcLyRPLbgFLRISoLFv4AMmCKXB6Ur+Ku2IwcOQcqx
igMman9FAbVzrBEnN4mypVbMKkIdDQk0YUx1i0USRVzBwkdpr53z9MB2qxW8sczc
tVHddQrqhS5T3W+FVUXNPJe+X798L0coUtB72f9Jn665E26EC8nQXgwJZlxfqqar
ZdDntAk+/gf7Mo+ARxJBpyoUn3MxDSOc6rxLfV3NVzgWuo/MmAaeV2ltcfaRUPIw
XOPn3vRQKHErHSk3cQIWwFG9xRJU41lzNpqmBLMilTAD4rrGyogqIuUKZSZ9wao2
xrpFLO3iUl4N3KCj6EYPlzRk9bkZEkrKNhxukMuHJvtq/ORM181E76O57DsY70hW
UuoPK9NNoQoTGLRbVqxnq25E6NZ4FG/ajJi74zQsNZa8D0fyUE1hBIaEBj1bpoYJ
nmRdCfwh2ejozFgVkrsklUjHeiUFGDu7w3EietzYZABpQSL6Bbr4uOYUMLULI53d
opDw70qiysfulr85cPhxVI7dFF7BlZ68vBqbpflhTJjqeBHk554e3mzU+mWPRL4Y
TqMfM9w0V5Ku2JSEGoeYf0/oPTjAPV9Fe0MAGFSdSRf86W439zHKIUUrREUwlp9L
xRMqsQeF9T3shsF4fgF2jrFb0/K4ZxnD6+IlhPDt7XrqoJ54daJ9mzsCAwEAAQ==
-----END RSA PUBLIC KEY-----

核心原因:PEM格式不匹配

PEM_read_PUBKEY专门用于加载PKCS#8格式的公钥(头部标识为-----BEGIN PUBLIC KEY-----),但你提供的是PKCS#1格式的RSA公钥(头部标识为-----BEGIN RSA PUBLIC KEY-----),格式不兼容直接导致加载失败。

解决办法

有两种直接可行的方案:

  1. 转换公钥格式:用OpenSSL命令把PKCS#1格式转成PKCS#8格式,命令如下:

    openssl rsa -in rsa_pub.pem -pubin -outform PEM -out pkcs8_pub.pem
    

    转换后的公钥头部会自动变为-----BEGIN PUBLIC KEY-----,此时用原代码的PEM_read_PUBKEY就能正常加载。

  2. 改用对应加载函数:如果不想转换格式,直接用专门加载PKCS#1格式RSA公钥的PEM_read_RSA_PUBKEY函数,替换原代码中的PEM_read_PUBKEY,再把返回的RSA*转为EVP_PKEY*即可:

    RSA *rsaPubKey = PEM_read_RSA_PUBKEY(publicKeyFile, NULL, NULL, NULL);
    EVP_PKEY *publicKey = EVP_PKEY_new();
    EVP_PKEY_assign_RSA(publicKey, rsaPubKey);
    

额外排查点

  • 检查文件是否成功打开:当前代码没做fopen的返回值检查,如果文件路径含特殊字符、权限不足,都会导致文件打开失败,建议加上:
    FILE *publicKeyFile = fopen(publicKeyFilePath.toStdString().c_str(), "rb");
    if (!publicKeyFile) {
        std::cout << "Failed to open public key file." << std::endl;
        return;
    }
    
  • 查看详细错误日志:在PEM_read_PUBKEY失败后调用ERR_print_errors_fp(stderr),可以打印OpenSSL的具体错误信息,快速定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 19:48:17