为什么curl无法使用受密码保护的密钥?

为什么curl无法使用受密码保护的密钥?,c,ssl,curl,https,libcurl,C,Ssl,Curl,Https,Libcurl,当客户端密钥上有密码时,Curl SSL连接失败 我试图发出https POST请求,客户端使用适当的证书和私钥与远程系统进行身份验证 在下面的代码中,如果“pathToAuthKey”指的是一个不受密码保护的密钥,则一切正常。没有错误。没有警告。连接已建立,一切正常 如果'pathToAuthKey'指的是相同的密钥,但受密码保护,并且我通过'authKeyPwd'字符串提供密码,我从Curl得到以下响应:- * About to connect() to 10.10.4.71 port 44

当客户端密钥上有密码时,Curl SSL连接失败

我试图发出https POST请求,客户端使用适当的证书和私钥与远程系统进行身份验证

在下面的代码中,如果“pathToAuthKey”指的是一个不受密码保护的密钥,则一切正常。没有错误。没有警告。连接已建立,一切正常

如果'pathToAuthKey'指的是相同的密钥,但受密码保护,并且我通过'authKeyPwd'字符串提供密码,我从Curl得到以下响应:-

* About to connect() to 10.10.4.71 port 443 (#1)
*   Trying 10.10.4.71...
* Connected to 10.10.4.71 (10.10.4.71) port 443 (#1)
* unable to load client key: -8178 (SEC_ERROR_BAD_KEY)
* NSS error -8178 (SEC_ERROR_BAD_KEY)
* Peer's public key is invalid.
* Closing connection 1
从本质上讲,Curl要么忽略我给它的密码,要么由于未知原因无法用指定的密码解密密钥。我给Curl的密码字符串就是这样;只是原始密码,所以是“abcde”,而不是“pass:abcde”(尽管我尝试了各种组合)

如果我使用命令行,我会得到相同的错误响应(尽管我不确定我在这里是否正确指定了密码)-

…或(?)

密钥和证书采用PEM格式。我在某个地方读到,他们应该包括“包”信息来处理Curl。我试过有和没有-这没有什么区别。我还尝试了以下代码的许多变体(以不同的顺序进行操作,尝试其他选项,等等),但没有成功

我从一个带有
---BEGIN ENCRYPTED PRIVATE key-----
头的密钥PEM格式开始,但在某个地方读到Curl不喜欢这样的内容,所以将其更改为
----BEGIN RSA PRIVATE key-----
。我已经尝试过密钥PEM文件,包括和不包括
Proc Type
DEK Info
Info(尽管我看不出SSL在没有此信息的情况下如何解码密钥,除非它只是尝试所有组合,直到成功),即-

我已尝试将密钥与证书文件相结合

证书是自签名的(尽管我看不出这会如何影响(缺少)密码成功)

最后一件事-我看到了名为
CURLOPT\u-SSLKEYPASSWD
CURLOPT\u-KEYPASSWD
选项。我两种都试过了,Curl似乎都接受,但我不知道是否有区别(官方文件没有提到后一种形式)

这是在Centos 6机器上。卷曲版本

curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.36 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp 
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets
任何帮助都将不胜感激

这是我的C代码-

curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl"); // Identify ourselves

// Set up timeout handler
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curlTimeoutCallback);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &transferStartTime);

// Set up the response handler
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlResponseCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

// Create HTTP request data
char postData[MAX_JSON_POST_LEN] = {"My POST data"};
int postLen = strlen(postData);

// Construct URL to send request to
char url[] = {"https://10.10.4.71/"};
curl_easy_setopt(curl, CURLOPT_URL, url);

curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); // ###

curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSLCERT, pathToAuthCert);

curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSLKEY, pathToAuthKey);

if (*authKeyPwd)
{
    curl_easy_setopt(curl, CURLOPT_KEYPASSWD, authKeyPwd);
}

// Try and simplify things for now by disabling verification of the remote system
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

// Send request
clock_gettime(CLOCK_MONOTONIC, &transferStartTime);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postLen);

CURLcode curlResp = curl_easy_perform(curl);

尝试使用
curl-k-v--cert./.ssh/authCert.pem--key./.ssh/authKey.pem--pass abcdehttps://10.10.4.71/
对于C源代码:首先尝试将authKeyPwd设置为字符串文字,如
“abcde”
为了排除读取密码短语ecurl-k-v-cert./.ssh/authCert.pem--key./.ssh/authKey.pem--pass abcde时出现的错误-相同的结果-“secu ERROR\u BAD\u key”我尝试了一个用于密钥的文本-没有我应该提到的幸运词-没有密码的密钥已使用密码从密钥中提取出来,因此,我知道密码/密钥加密没有问题。请尝试使用
curl-k-v--cert./.ssh/authCert.pem--key./.ssh/authKey.pem--pass abcdehttps://10.10.4.71/
对于C源代码:首先尝试将authKeyPwd设置为字符串文字,如
“abcde”
为了排除读取密码短语ecurl-k-v-cert./.ssh/authCert.pem--key./.ssh/authKey.pem--pass abcde时出现的错误-相同的结果-“secu ERROR\u BAD\u key”我尝试了一个用于密钥的文本-没有我应该提到的幸运词-没有密码的密钥已使用密码从密钥中提取出来,所以我知道密码/密钥加密没有错
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,FD47E79520E2C2A1E3B5D9B769C713A9

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .......etc.....
-----END RSA PRIVATE KEY-----
curl 7.29.0 (x86_64-redhat-linux-gnu) libcurl/7.29.0 NSS/3.36 zlib/1.2.7 libidn/1.28 libssh2/1.4.3
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp scp sftp smtp smtps telnet tftp 
Features: AsynchDNS GSS-Negotiate IDN IPv6 Largefile NTLM NTLM_WB SSL libz unix-sockets
curl_easy_setopt(curl, CURLOPT_USERAGENT, "curl"); // Identify ourselves

// Set up timeout handler
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, curlTimeoutCallback);
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &transferStartTime);

// Set up the response handler
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curlResponseCallback);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response);

// Create HTTP request data
char postData[MAX_JSON_POST_LEN] = {"My POST data"};
int postLen = strlen(postData);

// Construct URL to send request to
char url[] = {"https://10.10.4.71/"};
curl_easy_setopt(curl, CURLOPT_URL, url);

curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); // ###

curl_easy_setopt(curl, CURLOPT_SSLCERTTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSLCERT, pathToAuthCert);

curl_easy_setopt(curl, CURLOPT_SSLKEYTYPE, "PEM");
curl_easy_setopt(curl, CURLOPT_SSLKEY, pathToAuthKey);

if (*authKeyPwd)
{
    curl_easy_setopt(curl, CURLOPT_KEYPASSWD, authKeyPwd);
}

// Try and simplify things for now by disabling verification of the remote system
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);

// Send request
clock_gettime(CLOCK_MONOTONIC, &transferStartTime);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, postLen);

CURLcode curlResp = curl_easy_perform(curl);