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

时间:2011-05-25 12:13:06

标签: authentication curl client

我正在使用下面的snipped来设置证书和密钥以进行客户端身份验证。

  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

那么为什么它不起作用?

3 个答案:

答案 0 :(得分:3)

使用命令行curl,我使用.pem文件也得到了同样的错误,该文件也是从p12文件中使用openssl获得的,p12在浏览器中导入时也能正常进行客户端身份验证。就像你描述的那样,我想。

我的问题是由于.pem文件没有以正确的顺序列出证书而引起的:似乎文件中的每个证书都必须跟随其颁发者证书。 我编辑了文件并更改了部分的顺序,卷曲很高兴

为了记录,我的原始.p12文件是通过从Firefox备份证书获得的。

另请注意,就我而言,我没有收到提示输入密码的提示

curl: (58) unable to set private key file: 'alice.pem' type PEM
在密码提示之前

答案 1 :(得分:2)

我遇到了类似的问题,我发现问题与证书和私钥文件的文件权限有关。运行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

答案 2 :(得分:0)

感谢Hugh为openssl提示的线程和raugfer。后者:既有帮助又有误导性。 ; - )

实际上,我通过确保密钥文件的路径是正确的来解决了这个问题。这就是为什么openssl提示有误导性,有点帮助我检查我的PEM文件是否正常:

cURL需要完整路径,但没有'file://'前缀。虽然fopen对相对路径感到满意,但cURL并非如此。所以,我打开密钥文件的所有测试都是成功的,而cURL却没有。

顺便说一下:

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

,因为密码仅用于解密私钥,而PEM是默认密码。