使用SSL证书的cURL失败:错误58,无法设置私钥文件

20
我正在尝试使用cURL连接到远程主机。连接需要使用证书和受密码保护的私钥。到目前为止,我使用以下代码无法成功:
<?php
    $wsdl       = 'https://domain.com/?wsdl';
    $certFile   = getcwd() . '/auth/cert.pem';
    $keyFile    = getcwd() . '/auth/key.pem';
    $password   = 'pwd';

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL,           $wsdl);
    curl_setopt($ch, CURLOPT_SSLCERT,       $certFile);
    curl_setopt($ch, CURLOPT_SSLKEYPASSWD,  $password);
    curl_setopt($ch, CURLOPT_SSLKEY,        $keyFile);
    #curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
    #curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    #curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    $output = curl_exec($ch);

    var_dump(curl_errno($ch));
    var_dump(curl_error($ch));

我一直得到的结果是错误58: 无法设置私钥文件:'/home/.../domains/.../public_html/auth/key.pem'类型为PEM.

我已尝试的事情:

我相信问题在我的配置中,但不确定该从哪里查找。


“交换 key.pem 文件内容的顺序”。您的 key.pem 文件(包含私钥)应该只包含 1 个 PEM 编码部分(用于私钥)。需要更改的是证书文件的顺序。此私钥的客户端证书应位于顶部。 - Bruno
3个回答

26

我解决了这个问题。考虑到有关此问题的问题数量和不同的解决方案数量,其他人会从这个解决方案中受益。以下是解决方法:

我使用了 openssl CLI 程序将 .p12 密钥文件转换为 .pem 密钥文件。关键在于转换的方式。

首先,我使用以下命令进行转换,并出现了与问题描述相同的问题:

openssl pkcs12 -in key.p12 -out key.pem -nodes -clcerts

而以下命令则真正解决了问题:

openssl pkcs12 -in key.p12 -out key.pem -clcerts

有关更多信息,请参见我使用的来源:https://community.qualys.com/docs/DOC-3273


2
“-nodes”选项会移除密钥上的加密,这可能会与您在该情况下尝试使用密码产生冲突。 - Bruno
感谢提供额外的信息。我之前不知道这些。 - Ben Fransen
对我很有帮助!在这个问题上卡了好几天!谢谢你。 - S.Simkhada
似乎这个页面可以解释命令行选项:https://www.openssl.org/docs/manmaster/man1/openssl-pkcs12.html - Palec

3

如果其他人在搜索此问题时觉得有用,我想说一下,我最终发现CURLOPT_SSLCERT和CURLOPT_SSLKEY似乎无法使用相对路径。

这是在Windows上使用WAMP,php版本为5.5。


1
当我使用curl命令并且在搜索时发现了这个问题时,我遇到了相同的错误。我使用的命令是curl --key my.pem https://example.com/。
对我有效的解决方案是添加--cert选项,并指向相同的PEM文件。显然,这个PEM文件(在我的情况下)既包含了密钥又包含了证书。
我用curl命令进行了测试。
curl --cert my.pem  --key my.pem https://example.com/my/url

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