【问题标题】:PHP CURL and SSL certificate (or cert chain)PHP CURL 和 SSL 证书(或证书链)
【发布时间】:2011-10-31 02:39:50
【问题描述】:

美好的一天!

我有可通过 SSL (https://) 访问的 REST API。我想将正确的证书(或证书链)连同我编写的 PHP 和 CURL 脚本一起提出请求。

以下是来自我的目标 (http://api.vkontakte.ru) 的证书在 Firefox 中的样子:

http://speedcap.net/img/bc687485819715c65d6fe1e4ca1fdc40/1a2be.png

这是来自 Firefox 保存的“PEM 格式的证书链 X.509”的 sn-p (此处描述:http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/):

-----BEGIN CERTIFICATE-----
MIIFVzCCBD+gAwIBAgIHKx5Ov2FOejANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
[..skip...]
0npsf5fkvT8E13NgVY0PK6V/baMTlTgWXKQZ
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIE3jCCA8agAwIBAgICAwEwDQYJKoZIhvcNAQEFBQAwYzELMAkGA1UEBhMCVVMx
[..skip...]
qDTMBqLdElrRhjZkAzVvb3du6/KFUJheqwNTrZEjYx8WnM25sgVjOuH0aBsXBTWV
U+4=
-----END CERTIFICATE-----

这是 CURL 初始化的代码示例:

$this->ch = curl_init();
    curl_setopt_array($this->ch, array(

        CURLOPT_TIMEOUT => 30,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_AUTOREFERER => TRUE,
        CURLOPT_FOLLOWLOCATION => TRUE,

        CURLOPT_SSL_VERIFYPEER => TRUE,
        CURLOPT_SSL_VERIFYHOST => 2,
        CURLOPT_CAINFO => <path to my cert>,        
    )); 

我收到 CURL 错误 60 (CURLE_SSL_CACERT) 抱怨证书错误。

我尝试过的:

  • 我已验证使用了我的证书文件,因为当我指定错误的路径时,它会抱怨找不到证书(错误 70)

  • 我已使用 Facebook SDK 及其证书链检查我的 CURL 是否适用于此类设置

  • 我尝试导出不同的链(包括或不包括)链中的最后一个证书

  • 试过CURLOPT_SSL_VERIFYHOST =&gt; 1

欢迎任何想法!

【问题讨论】:

    标签: php ssl curl https


    【解决方案1】:

    这些是似乎可行的步骤:

    1. 在firefox中访问https url
    2. 点击绿色栏,点击箭头,然后点击“更多信息”
    3. 点击“查看证书”,然后点击顶部的“详细信息”标签
    4. 然后点击每个级别并导出每个证书:

      根 CA

      服务器 CA

      example-website.invalid

      您应该将所有三个文件都保存到您的计算机上。将所有三个文件复制到一个文件中,例如custom_name_cert.pem

    将该 pem 文件复制到 PHP 可访问的目录中,理想情况下该文件的权限为 644。您甚至可以选择 444 以防止篡改,并在需要更新时将其更改为 644。

    然后更新你代码中的路径,例如:

    CURLOPT_CAINFO =&gt; '/var/www/certs/custom_name_cert.pem'

    警告:当网站更新其 SSL 证书时,上述文件可能会过期,并且 HTTPS cURL 调用可能会失败,从而破坏您的应用程序。希望有人会在这里回答一个自动更新此文件的好方法。

    【讨论】:

    • 提示:导出证书时,请选择Base-64 encoded X.509 (.CER)格式,否则无法复制到.pem文件中
    【解决方案2】:

    几年前,Vkontakte 从 vkontakte.ru 域转移到了 vk.com。他们也改变了他们的 api 处理程序 url。 这是我的解决方案:

    1. 在 Firefox 中打开 https://vk.com/
    2. 将此站点的证书链导出为 X.509
    3. 将目标网址从http://api.vkontakte.ru 更改为https://api.vk.com/

    这是我的带有 curl 选项的代码:

    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    curl_setopt($ch, CURLOPT_CAINFO, getcwd() ."/ffchainvk.crt"); //  ok
    

    ffchainvk.crt 是导出证书链的文件。

    【讨论】:

    • 感谢您的跟进,但在提出问题时,域 vkontakte.ru 仍在使用中。后来我发现问题出在不完整的证书链中。当从 firefox 包 (curl.haxx.se/docs/sslcerts.html) 手动创建证书链时,它可以工作。
    • 昨天我也无法为“vkontakte.ru”建立正确的链,但是使用来自 Firefox 的捆绑包,它可以按预期工作。另一个问题是来自 Firefox 的包非常大(~300kb)。你知道链中缺少哪个证书吗?
    • 现在找不到这个文件,但它是根证书之一,我刚刚从 firefox 包中删除了证书,直到它停止工作。
    【解决方案3】:

    Curl 在服务器上的不同位置使用 CA 证书,而不是在系统的其余部分(如桌面)中使用。我之前必须将 CA 证书安装到文件系统中。 PHP libcurl 也将使用命令行实用程序使用的库。请参阅http://curl.haxx.se/docs/sslcerts.html

    【讨论】:

    • 谢谢,它适用于这个包:curl.haxx.se/docs/caextract.html。但是我应该如何为我的目标站点提取正确的证书呢?
    • 我试图将那个 ca 文件剥离为我链中的证书,但它不起作用:(
    • 我以前没有尝试过这种风选过程。只要您从捆绑包中取出一个证书,它就会失败吗?如果是这样,则可能是格式问题。否则,您可能需要继续试验。
    • 当我删除它时,它可以工作,当我删除除证书之外的所有文件时,我将它链接在没有。也许我以错误的方式解释了证书链?
    • 您只需要将 CA 证书添加到您的受信任 CA 证书列表中。 CA证书是顶级证书,CN为Go Daddy Class 2 CA
    猜你喜欢
    • 2021-02-20
    • 2012-09-17
    • 1970-01-01
    • 2015-05-23
    • 2013-09-28
    • 2016-07-08
    • 2014-02-06
    • 2022-01-26
    • 2016-06-01
    相关资源
    最近更新 更多