无法使用libcurl访问需要客户端身份验证的网站

5
我正在使用以下代码片段来设置客户端身份验证的证书和密钥。
  curl_easy_setopt(curl,CURLOPT_SSLCERT,"clientCert.pem");
  curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
  curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
  curl_easy_setopt(curl,CURLOPT_SSLKEY,"privateKey.pem");
  curl_easy_setopt(curl,CURLOPT_SSLKEYPASSWD,"changeit");
  curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");

证书没有密码,我不知道为什么会有SSLCERTPASSWD选项,所以我只提供了一个虚拟值。 当我在Linux上运行程序时,我收到了错误代码58和错误消息:无法设置私钥文件:“privateKey.pem”类型为PEM。
然而,在Windows上,我收到了错误消息:无法使用客户端证书(未找到密钥或密码错误?)
这似乎表明证书和密钥不匹配,但我不知道原因。我使用openssl命令从p12文件中提取了证书和密钥。 我用于提取密钥的命令是:
openssl.exe pkcs12 -in client.p12 -nocerts -out privateKey.pem

提取证书的命令是

openssl.exe pkcs12 -in client.p12 -nokeys -out clientCert.pem

p12文件已成功用于浏览器访问客户端认证网址。 在我开枪之前请帮忙。

编辑: 这里有证据表明私钥和证书相对应:

[debugbld@nagara ~/curlm]$ openssl x509 -noout -modulus -in clientCert.pem | openssl md5
d7207cf82b771251471672dd54c59927

[debugbld@nagara ~/curlm]$ openssl rsa -noout -modulus -in privateKey.pem | openssl md5
Enter pass phrase for privateKey.pem:
d7207cf82b771251471672dd54c59927

那么为什么它不能工作呢?

1
我在命令行curl中遇到了相同的结果。我将客户端证书和密钥连接到一个文件中,并尝试如下: curl --cert concatenatedCert.pem --cert-type PEM --cacert cabundle.crt https://inaveo:8775/DataIntegrationService/WebService/WS_test/ 输入PEM密码: curl:(58)无法设置私钥文件:'concatenatedCert.pem' 类型为PEM - Walking Corpse
3个回答

3
使用命令行curl时,我使用了一个由openssl从.p12文件获取的.pem文件,结果出现了相同的错误。当在浏览器中导入.p12文件时,该文件也能够正常进行客户端身份验证。就像你所描述的那样。
我的问题是由于.pem文件未按正确顺序列出证书引起的:似乎文件中的每个证书都必须跟随其发行者证书。我编辑了文件并更改了部分的顺序,curl很愉快地工作了。
记录一下,我的原始.p12文件是通过从Firefox备份证书获得的。
另请注意,在我的情况下,我没有被提示输入密码,而是收到了...
curl: (58) unable to set private key file: 'alice.pem' type PEM

在密码提示之前


3

我曾经遇到类似的问题,后来发现问题与证书和私钥文件的文件权限有关。运行PHP的进程没有读取这些文件的权限。

你可以尝试以下代码(对我解决问题很有帮助):

$result=openssl_get_privatekey('file://path/to/private/key.pem','password');

检查返回值是否不是 false 并且没有出现任何错误。我得到了以下结果:

file_get_contents(/path/to/private/key.pem): failed to open stream: Permission denied

0

感谢Hugh提供的线索以及raugfer提供的openssl提示。后者既有帮助又有误导。;-)

实际上,我通过确保密钥文件路径正确来解决了问题。这就是为什么openssl提示会让我产生误导的原因,尽管它帮助我检查我的PEM文件是否正确:

cURL需要完整路径,但没有'file://'前缀。而fopen可以使用相对路径,但cURL不行。因此,尽管打开密钥文件的所有测试都成功了,但cURL却没有。

Btw.:

curl_easy_setopt(curl,CURLOPT_SSLCERTPASSWD,"changeit");
curl_easy_setopt(curl,CURLOPT_SSLCERTTYPE,"PEM");
curl_easy_setopt(curl,CURLOPT_SSLKEYTYPE,"PEM");

不需要,因为密码仅用于解密私钥,而PEM是默认格式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接