C++ SSL_CTX_use_PrivateKey_file() 失败

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19029647/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:26:26  来源:igfitidea点击:

SSL_CTX_use_PrivateKey_file() failed

c++sslopenssl

提问by jfly

I'm writing a client application on Windows that establishes an SSL connection to a server, and the server requests client certificate for authentication. The server provides me a .pfx file, then I use openssl command line tool to get the certificate and the private key like this:

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

openssl pkcs12 -in filename.pfx -clcerts -nokeys -out cert.pem
openssl pkcs12 -in filename.pfx -nocerts -out key.pem

after that, I try to load the certificate and the private key with functions from openssl as below, but SSL_CTX_use_PrivateKey_file()always failed, the error message is "error:0906D06C:PEM routines:PEM_read_bio:no start line", I can't figure it out why, can anyone give me some enlightenment? Here is the code.

之后,我尝试从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;
};

采纳答案by jfly

I've solved this problem myself. I generated the key.pem using OpenSSL for Windows, when the CMD prompts me to type in the pass phrase, I just typed a Enter since I needn't a pass phrase, but the key.pem was invalid(neither BEGINnor ENDmarkers). When I generate the private key in Linux, the terminal prompts I must type a pass phrase and I do.Then I remove the key pass phrase using this command:

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

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

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

After that, I open the key.pem in a text editor, it starts off with -----BEGIN RSA PRIVATE KEY-----and end up with -----END RSA PRIVATE KEY-----. And SSL_CTX_use_PrivateKey_file() just works fine!

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

回答by TheMagicCow

In my case the error was because the PEM file did not contain both a key and a certificate.

就我而言,错误是因为 PEM 文件不包含密钥和证书。

Make sure your file contains both sections:

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

-----BEGIN PRIVATE KEY----- jhajk838383jks.....
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE----- yoe55wjcxnshre.....
-----END CERTIFICATE KEY-----

I catenated .keyand .crtfiles I already had in my Apache configuration to make a .pemfile.

我链中.key.crt我已经在我的Apache配置文件,使一个.pem文件。

The 'no start line' error is certainly misleading as you can have a perfectly good "BEGIN" line in your PEM file and still get the error.

'no start line' 错误肯定会产生误导,因为您可以在 PEM 文件中有一个非常好的“BEGIN”行,但仍然会出现错误。

回答by Karthik

The error error:0906D06C:PEM routines:PEM_read_bio:no start lineis because in both the cert.pem as well as key.pem, don't start off with -----BEGIN CERTIFICATE-----and -----BEGIN ENCRYPTED PRIVATE KEY-----.

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

If you open up your cert.pem and key.pem in a text editor and yank off whatever is there before the BEGINmarkers, you should be good.

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

When you create a certificate and a key pair using Certificate Signing Request, you won't get this additional information.

当您使用Certificate Signing Request创建证书和密钥对时,您将不会获得此附加信息。

回答by Cyril

Under openssl directory demo/openssl there is a client example.

在 openssl 目录 demo/openssl 下有一个客户端示例。

Change:

改变:

meth = SSLv2_client_method();

in your case to:

在你的情况下:

meth = SSLv23_client_method();

Try this example and see where it fails.

试试这个例子,看看它在哪里失败。

Are you sure that the key password is 123456 ?

您确定密钥密码是 123456 吗?

回答by Ankur Tiwari

I had the same problem in NGINX while installing the SSL certificate and I resolved using the following step:

我在安装 SSL 证书时在 NGINX 中遇到了同样的问题,我使用以下步骤解决了这个问题:

  • Go to the folder where you have your certificate and pem files
  • Open your ca-bundle.crtfile and copy everything, sudo nano your fileNameselect all and copy. the file looks like
  • 转到您拥有证书和 pem 文件的文件夹
  • 打开您的ca-bundle.crt文件并复制所有内容,全sudo nano your fileName选并复制。该文件看起来像

-----BEGIN CERTIFICATE----- MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT ..........

-----END CERTIFICATE-----

-----BEGIN CERTIFICATE----- MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsIEluYy4xMTAvBgNVBAsTKEdv ..........

-----END CERTIFICATE-----

-----BEGIN CERTIFICATE----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE .......... -----END CERTIFICATE-----

-----开始证书----- MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhYBgnvt

-----结束证书-----

----- 开始认证----- MIIEfTCCA2WgAwIBAgIDG+cVMA0GCSqGSIb3DQEBCwUAMGMxCzAJBgNVBAYTAlVT MSEwHwYDVQQKExhUaGUgR28gRGFkZHkgR3JvdXAsAvIEluY.....

-----结束证书-----

-----开始证书----- MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQ.....

  • Open your pem file using sudo nano your fileName.pem
  • You will see some code like
  • 使用打开您的 pem 文件 sudo nano your fileName.pem
  • 你会看到一些代码,比如

-----BEGIN CERTIFICATE----- MIIGLzCCBRegAwIBAgIIWI4ndTQi3MwwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV MAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB/wQEAwIF oDA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkaWcy

-----END CERTIFICATE-----

----- BEGIN CERTIFICATE ----- MIIGLzCCBRegAwIBAgIIWI4ndTQi3MwwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV MAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB / wQEAwIF oDA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vY3JsLmdvZGFkZHkuY29tL2dkaWcy

-----结束证书-----

  • After -----END CERTIFICATE-----paste all the code copied from ca-bundle.crtfile and save it
  • Restart your Nginxserver using following command sudo service nginx restart
  • -----END CERTIFICATE-----粘贴复制的所有代码ca-bundle.crt并保存文件
  • Nginx使用以下命令重新启动服务器sudo service nginx restart

The above steps worked for me in my Nginx and SSL configuration

上述步骤在我的 Nginx 和 SSL 配置中对我有用