PHP CURL和SSL证书(或证书链)


PHP CURL and SSL certificate (or cert chain)

大家好!

我有REST API,可以通过SSL访问(https://).)我想把正确的证书(或证书链)连同我的脚本编写的PHP和CURL使请求。

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

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

以下是Firefox保存的"PEM格式的证书链X.509"的片段(在这里描述: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 init的代码示例:

$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 error 60 (CURLE_SSL_CACERT)抱怨错误的证书。

我试过了:

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

  • 我已经检查了Facebook SDK和他们的证书链,我的CURL工作与这样的设置

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

  • 已尝试CURLOPT_SSL_VERIFYHOST => 1

欢迎任何想法!

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

  1. 在firefox中打开https://vk.com/
  2. 导出此站点的X.509证书链
  3. 将目标url从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为导出的证书链文件

Curl在服务器上的一个单独位置使用CA证书,而不是系统的其他部分,就像桌面一样。我以前不得不在文件系统中安装CA证书。PHP libcurl也将使用命令行实用程序使用的库。

这些步骤似乎是有效的:

  1. 在firefox中访问https url
  2. 点击绿色条,点击箭头,点击"更多信息"
  3. 点击"查看证书",然后点击顶部的"详细信息"选项卡
  4. 然后点击每个级别,导出每个证书:

    根CA

    服务器CA

    example-website.invalid

    你应该把这三个文件都保存到你的电脑上。将这三个文件复制到一个文件中,例如custom_name_cert.pem

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

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

CURLOPT_CAINFO => '/var/www/certs/custom_name_cert.pem'

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