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
SSL_CTX_use_PrivateKey_file() failed
提问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 BEGIN
nor END
markers). 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 无效(既不BEGIN
是END
标记也不是)。当我在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 .key
and .crt
files I already had in my Apache configuration to make a .pem
file.
我链中.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 line
is 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 BEGIN
markers, 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.crt
file and copy everything,sudo nano your fileName
select 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 fromca-bundle.crt
file and save it - Restart your
Nginx
server using following commandsudo 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 配置中对我有用