SSL_CTX_use_PrivateKey_file()失败

jfl*_*fly 10 c++ ssl openssl

我正在Windows上编写一个客户端应用程序,它建立与服务器的SSL连接,服务器请求客户端证书进行身份验证.服务器提供了一个.pfx文件,然后我使用openssl命令行工具来获取证书和私钥,如下所示:

openssl pkcs12 -in filename.pfx -clcerts -nokeys -out cert.pem
openssl pkcs12 -in filename.pfx -nocerts -out key.pem
Run Code Online (Sandbox Code Playgroud)

在那之后,我尝试加载证书,并与OpenSSL的功能如下私钥,但是SSL_CTX_use_PrivateKey_file()总是失败,错误消息" error:0906D06C:PEM routines:PEM_read_bio:no start line",我弄不明白,为什么,任何人都可以给我一些启示?这是代码.

#include "openssl/ssl.h"
#include "openssl/err.h"
#include <stdio.h>
#include <string>

int InitClientCtx()
{
    OpenSSL_add_ssl_algorithms();

    SSL_CTX* m_pClientCtx;
    m_pClientCtx = SSL_CTX_new(SSLv23_method());

    if(!m_pClientCtx)
    {
        return -1;
    }

    ::SSL_CTX_set_options(m_pClientCtx, SSL_OP_ALL);  //for well-known bugs

    int nRet = 0;

    std::string sCertFilePath = "C:\\cert.pem";

    nRet = SSL_CTX_use_certificate_chain_file(m_pClientCtx, sCertFilePath.c_str());

    std::string sKeyPassWord = "123456";

    SSL_CTX_set_default_passwd_cb_userdata(m_pClientCtx, (void*)(sKeyPassWord.c_str()));

    std::string sKeyFilePath = "C:\\key.pem";

    // this method returned 0, which means it failed.
    nRet = SSL_CTX_use_PrivateKey_file(m_pClientCtx, sKeyFilePath.c_str(), SSL_FILETYPE_PEM);

    SSL_load_error_strings();
    unsigned long n = ERR_get_error();
    char buf[1024];
    printf("%s\n", ERR_error_string(n, buf));

    nRet = SSL_CTX_check_private_key(m_pClientCtx);
    if (nRet <= 0)
    {
        return -1;
    }

    /*std::string sCACertFilePath;

    nRet = SSL_CTX_load_verify_locations(m_pClientCtx, sCACertFilePath.c_str(), NULL);*/

    return 0;
}

int main()
{
    InitClientCtx();
    return 0;
};
Run Code Online (Sandbox Code Playgroud)

小智 11

在我的情况下,错误是因为PEM文件不包含密钥和证书.

确保您的文件包含以下两个部分:

-----BEGIN PRIVATE KEY----- jhajk838383jks.....
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE----- yoe55wjcxnshre.....
-----END CERTIFICATE KEY-----
Run Code Online (Sandbox Code Playgroud)

我链接.key.crt我已经在Apache配置中创建的.pem文件来创建文件.

"无起始线"错误肯定会产生误导,因为您可以在PEM文件中有一个非常好的"BEGIN"行,但仍会出现错误.


jfl*_*fly 6

我自己解决了这个问题。我使用 OpenSSL for Windows 生成了 key.pem,当 CMD 提示我输入密码短语时,我只是输入了 Enter,因为我不需要密码短语,但 key.pem 无效(既不是标记BEGIN也不是END)。当我在 Linux 中生成私钥时,终端提示我必须输入密码短语,我就这样做了。然后我使用以下命令删除密钥密码短语:

openssl rsa -in key.pem -out newkey.pem

之后,我在文本编辑器中打开 key.pem,它以 开头-----BEGIN RSA PRIVATE KEY-----并以 结尾-----END RSA PRIVATE KEY-----。SSL_CTX_use_PrivateKey_file() 工作正常!


Kar*_*hik 5

该错误error:0906D06C:PEM routines:PEM_read_bio:no start line是因为在cert.pem和key.pem中都不要以-----BEGIN CERTIFICATE-----和开头-----BEGIN ENCRYPTED PRIVATE KEY-----

如果您在文本编辑器中打开cert.pem和key.pem并删除BEGIN标记之前的所有内容,那么您应该会很好。

使用“ 证书签名请求”创建证书和密钥对时,不会获得此附加信息。