如何验证login.live.com SSL证书与cURL,PHP和Windows XAMPP [英] How to verify login.live.com SSL certificate with cURL, PHP and Windows XAMPP

查看:352
本文介绍了如何验证login.live.com SSL证书与cURL,PHP和Windows XAMPP的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在PHP中使用cURL向 https://login.live.com/oauth20_token.srf 发出HTTP请求。 cURL总是给出以下错误消息: SSL证书问题:无法获取本地颁发者证书(错误no 60)。这是我的设置




  • Apache Friends XAMPP v5.6.3在Windows 7 64位);这包括:

  • PHP 5.6.3

  • cURL 7.39.0

  • OpenSSL / 1.0.1i



我包含了 ca-bundle.crt 文件从 cURL CA Extract 网站与 CURLOPT_CAINFO 选项。此文件包括 VeriSign 3类公共主证书颁发机构 - G5 证书。此证书与Firefox为 https://login.live.com/oauth20_token.srf 显示的根证书相同。



这是我的测试PHP脚本

  ;?php 

// $ url ='https://api.onedrive.com';
$ url ='https://login.live.com/oauth20_token.srf';

$ ch = curl_init($ url);

$ errorLog = fopen('php:// temp','rw');
curl_setopt($ ch,CURLOPT_VERBOSE,true);
curl_setopt($ ch,CURLOPT_STDERR,$ errorLog);
curl_setopt($ ch,CURLOPT_RETURNTRANSFER,true);

curl_setopt($ ch,CURLOPT_SSL_VERIFYPEER,true);
curl_setopt($ ch,CURLOPT_CAINFO,__DIR__。DIRECTORY_SEPARATOR。'ca-bundle.crt');

curl_exec($ ch);

$ error = curl_error($ ch);
if($ error!=''){
echo### cURL error:### \\\
;
echo curl_errno($ ch)。 ''。 curl_error($ ch)。 \\\
\\\
;
}

curl_close($ ch);

echo### cURL verbose output:### \\\
;
rewind($ errorLog);
echo stream_get_contents($ errorLog);

它会生成以下输出

  ### cURL错误:### 
60 SSL证书问题:无法获取本地颁发者证书

### cURL详细输出:###
*在DNS缓存中找到主机名
*尝试131.253.61.98 ...
*连接到login.live.com (131.253.61.98)端口443(#0)
*成功设置证书验证位置:
* CAfile:C:\ xampp\htdocs\curl\ca-bundle.crt
CApath:none
* SSL证书问题:无法获取本地颁发者证书
*关闭连接0


b $ b

我测试了另一个网址 https://api.onedrive.com 。根据Firefox这个网站的根证书是巴尔的摩Cyber​​Trust根证书,它也包括在 ca-bundle.crt 文件。对于此网址,cURL按预期工作,脚本生成以下输出

  ### cURL详细输出:### 
*重建URL到:https://api.onedrive.com/
*在DNS缓存中找到主机名
*尝试134.170 .106.24 ...
*连接到api.onedrive.com(134.170.106.24)端口443(#0)
*成功设置证书验证位置:
* CAfile:C:\ xampp \htdocs\curl\ca- bundle.crt
CApath:none
*使用TLSv1.2 / ECDHE-RSA-AES256-SHA384的SSL连接
*服务器证书:
* subject:C = US; ST = WA; L = Redmond; O = Microsoft Corporation; OU = Microsoft Corporation; CN = storage.live.com
*开始日期:2015-03-03 21:28:09 GMT
*到期日期:2017-03-02 21:28:09 GMT
* subjectAltName:api.onedrive.com matched
* issuer:C = US; ST =华盛顿; L = Redmond; O = Microsoft Corporation; OU = Microsoft IT; CN = Microsoft IT SSL SHA2
* SSL证书验证确定。
> GET / HTTP / 1.1
主机:api.onedrive.com
接受:* / *

< HTTP / 1.1 400错误请求
< Content-Length:264
< Content-Type:application / json
<服务器:Microsoft-HTTPAPI / 2.0
< P3P:CP =BUS CUR CONO FIN IVDo ONL OUR PHY SAMo TELo
< X-MSNSERVER:BN1305____PAP241
< X-QosStats:{ApiId:0,ResultType:2,SourcePropertyId:0,TargetPropertyId:42}
& X-ThrowSite:7ecf.1484
< X-AsmVersion:UNKNOWN; 19.15.0.0
<日期:星期二,2015年3月17日17:34:56 GMT
<
* Connection#0 to host api.onedrive.com left intact

VeriSign 3级公共主要证书颁发机构 - 证书 https://login.live.com/oauth20_token.srf 与Firefox,并使用该证书,而不是 ca-bundle.crt 文件。我还添加了中间证书 VeriSign 3级扩展验证SSL SGC CA 。两者都没有帮助。



如何验证login.live.com SSL证书与给定的设置?将 CURLOPT_SSL_VERIFYPEER 设置为 false 不是我要找的。

更新:我做了一些更多的研究,现在看起来像这样

p>我找到了解决方案。简单的答案是:使用 VeriSign Class 3公共主CA证书,序列号为3c 91 31 cb 1f f6 d0 1b 0e 9a b8 d0 44 bf 12是,链接到 Symantec网站(根目录2)使用cURL验证 login.live.com:443 / OpenSSL。在Linux中,此证书可能以OpenSSL可以使用的方式预安装(即使您提供了一个具有 CURLOPT_CAINFO 的证书文件也会使用)。



更长的答案是:cURL使用OpenSSL进行HTTPs连接。当前OpenSSL版本不会验证证书链,其中根证书是受信任的,但是由另一个不受信任的根证书签署。这适用于 VeriSign 3级公共主要证书颁发机构 - G5证书,由Firefox正确显示为 login.live.com:443的根证书,其中包含在 ca-bundle.crt 中。此根证书再次由上述 VeriSign Class 3公共主CA证书。如果这最后提到的根证书不是OpenSSL的受信任的根证书,证书链的验证失败。



我发现这个信息



在Windows服务器上修复VeriSign证书。

I need to make a HTTP request to https://login.live.com/oauth20_token.srf with cURL in PHP. cURL always gives the following error message: SSL certificate problem: unable to get local issuer certificate (error no 60). This is my setup:

  • Apache Friends XAMPP v5.6.3 on Windows 7 64-bit (no configuration changes); this includes:
  • PHP 5.6.3
  • cURL 7.39.0
  • OpenSSL/1.0.1i

I included the ca-bundle.crt file from the cURL CA Extract website with the CURLOPT_CAINFO option. This file includes the VeriSign Class 3 Public Primary Certification Authority - G5 certificate. This certificate is identical to the root certificate which Firefox displays for https://login.live.com/oauth20_token.srf.

This is my test PHP script:

<?php

// $url = 'https://api.onedrive.com';
$url = 'https://login.live.com/oauth20_token.srf';

$ch = curl_init($url);

$errorLog = fopen('php://temp', 'rw');
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, $errorLog);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . DIRECTORY_SEPARATOR . 'ca-bundle.crt');

curl_exec($ch);

$error = curl_error($ch);
if ($error != '') {
  echo "### cURL error: ###\n";
  echo curl_errno($ch) . ' ' . curl_error($ch) . "\n\n";
}

curl_close($ch);

echo "### cURL verbose output: ###\n";
rewind($errorLog);
echo stream_get_contents($errorLog);

It generates the following output:

### cURL error: ###
60 SSL certificate problem: unable to get local issuer certificate

### cURL verbose output: ###
* Hostname was found in DNS cache
*   Trying 131.253.61.98...
* Connected to login.live.com (131.253.61.98) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: C:\xampp\htdocs\curl\ca-bundle.crt
  CApath: none
* SSL certificate problem: unable to get local issuer certificate
* Closing connection 0

I tested another URL, https://api.onedrive.com. According to Firefox this site's root certificate is the Baltimore CyberTrust Root certificate, which also is included in the ca-bundle.crt file. For this URL cURL works as expected and the script generates the following output:

### cURL verbose output: ###
* Rebuilt URL to: https://api.onedrive.com/
* Hostname was found in DNS cache
*   Trying 134.170.106.24...
* Connected to api.onedrive.com (134.170.106.24) port 443 (#0)
* successfully set certificate verify locations:
*   CAfile: C:\xampp\htdocs\curl\ca-bundle.crt
  CApath: none
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-SHA384
* Server certificate:
*    subject: C=US; ST=WA; L=Redmond; O=Microsoft Corporation; OU=Microsoft Corporation; CN=storage.live.com
*    start date: 2015-03-03 21:28:09 GMT
*    expire date: 2017-03-02 21:28:09 GMT
*    subjectAltName: api.onedrive.com matched
*    issuer: C=US; ST=Washington; L=Redmond; O=Microsoft Corporation; OU=Microsoft IT; CN=Microsoft IT SSL SHA2
*    SSL certificate verify ok.
> GET / HTTP/1.1
Host: api.onedrive.com
Accept: */*

< HTTP/1.1 400 Bad Request
< Content-Length: 264
< Content-Type: application/json
< Server: Microsoft-HTTPAPI/2.0
< P3P: CP="BUS CUR CONo FIN IVDo ONL OUR PHY SAMo TELo"
< X-MSNSERVER: BN1305____PAP241
< X-QosStats: {"ApiId":0,"ResultType":2,"SourcePropertyId":0,"TargetPropertyId":42}
< X-ThrowSite: 7ecf.1484
< X-AsmVersion: UNKNOWN; 19.15.0.0
< Date: Tue, 17 Mar 2015 17:34:56 GMT
< 
* Connection #0 to host api.onedrive.com left intact

I also exported the VeriSign Class 3 Public Primary Certification Authority - G5 certificate from https://login.live.com/oauth20_token.srf with Firefox and used that certificate instead of the ca-bundle.crt file. I also added the intermediate certificate VeriSign Class 3 Extended Validation SSL SGC CA. Both did not help.

How can I verify the login.live.com SSL certificate with the given setup? Setting CURLOPT_SSL_VERIFYPEER to false is not what I am looking for.

UPDATE: I did some more research and now it looks like this might be an OpenSSL issue on Windows.

解决方案

I found the solution. The short answer is: Use VeriSign Class 3 Public Primary CA certificate with serial number 3c 91 31 cb 1f f6 d0 1b 0e 9a b8 d0 44 bf 12 be which is linked on Symantec's website (Root 2) to validate login.live.com:443 with cURL/OpenSSL in Windows. In Linux this certificate will probably be preinstalled in a way OpenSSL can use (and will use even if you supply a certificate file with CURLOPT_CAINFO).

The longer answer is: cURL uses OpenSSL for HTTPs connections. Current OpenSSL versions won't validate a chain of certificates where a root certificate is trusted but is signed by another untrusted root certificate. This is true for the VeriSign Class 3 Public Primary Certification Authority - G5 certificate which is correctly displayed by Firefox as a root certificate for login.live.com:443 and which is included in ca-bundle.crt. This root certificate is again signed by the above mentioned VeriSign Class 3 Public Primary CA certificate. If this last mentioned root certificate is not known as a trusted root certificate to OpenSSL, validation of the certificate chain fails.

I found this information

这篇关于如何验证login.live.com SSL证书与cURL,PHP和Windows XAMPP的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆