无法使 PHP cURL SSL 工作

Can't Get PHP cURL SSL To Work

我正在尝试将 PHP cURL 从 https://www.google.com 获取到 return headers。我这样做是为了了解如何配置 PHP curl_setopt 参数以正确使用 SSL 网站。 "correctly" 我的意思是我希望 cURL 应用 CURLOPT_SSL_VERIFYPEER 参数来验证服务器的安全证书。

这对我来说是新的领域。我对这个过程是如何工作的有一个模糊的理解,但我无法得到以下代码 return the google.com headers:

<?php

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.google.com');

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,1);
curl_setopt($ch, CURLOPT_CAINFO, "c:/wamp/www/certificates/googleCA.cer");

curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_NOBODY, true); // HTTP request is 'HEAD only'
curl_setopt($ch, CURLOPT_USERAGENT,'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Firefox/31.0');
curl_setopt($ch, CURLOPT_REFERER,'https://www.google.com');
$headers=curl_exec($ch);

print_r($headers);

echo "Got to end!";

?>

我已按照以下 link 中的说明使用 IE11 从 Windows 中提取 google.com 证书的副本:

http://unitstep.net/blog/2009/05/05/using-curl-in-php-to-access-https-ssltls-protected-sites/

上面link描述的证书提取似乎没问题。我在 Windows 7 64 位机器上。我将来自 IE11 的 top-level 证书作为 'Base-64 encoded x.509 (CER)' 文件保存到我的 'c:\WAMP\www\certificates\' 文件夹中作为 'googleCA.cer'。然后我将 CURLOPT_CAINFO 参数设置为 'c:/wamp/www/certificates/googleCA.cer'。当我执行 PHP 代码时,google headers AREN'T returned with CURLOPT_VERIFYPEER 参数设置为“1”(我知道设置CURLOPT_VERIFYPEER 到“0” 指示 cURL 不验证服务器证书,return headers,但这是一个完全不安全的配置,我不想使用)。 =16=]

这感觉像是我使用 IE11 从 Windows 导出的证书的问题。我还发现这个 link 描述了从 cURL 网站下载 cacert.pem 文件:

https://curl.haxx.se/docs/caextract.html

当我点击上面的 link 时,我得到了在 IE11 中显示的 caextract 文件的文本。我不知道下一步该怎么做。任何帮助将不胜感激。

非常感谢! --

编辑:这是 googleCA.cer 文件的内容:

-----BEGIN CERTIFICATE-----
MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
-----END CERTIFICATE-----

这个问题的答案是https://www.google.com in IE11, "GeoTrust Global CA," is cross-rooted to an older GeoTrust root certificate named "Equifax Secure Certificate Authority." When the "GeoTrust Global CA" certificate that displays as the root in the 3-certificate chain showing in my IE11 is used by my PHP script as the root certificate for https://www.google.com my PHP script can't authenticate https://www.google.com's certificate BECAUSETHE REAL ROOT CERTIFICATE FOR https://www.google.com ISN'T THE "GeoTrust Global CA" CERTIFICATE BUT THE GeoTrust "Equifax Secure Certificate Authority" certificate. Once I figured this out, I used the "Equifax Secure Certificate Authority" in my PHP .PEM file and I successfully validated the https://www.google.com证书显示的根证书。

您可以通过执行以下操作查看交叉根目录是如何发生的(我为此使用了 IE11):

  1. 打开一个空白https://www.google.com网页
  2. 单击 URL window 中的挂锁图标,然后单击 "View certificates."
  3. https://www.google.com 的证书 window 出现。单击证书路径选项卡。将显示三个证书的证书链。 "GeoTrust Global CA" 证书显示为根证书 - 但事实并非如此。
  4. 关闭证书window。在“开始”菜单的 "Run" 框中(我使用的是 Windows 7)键入 "certmgr.msc" 并单击 "OK" 按钮。这将启动 Windows' 证书管理器。
  5. 单击左侧窗格中的 "Trusted Root Certification Authorities" 条目,然后单击 "Certificates."
  6. 在右窗格中,找到 "GeoTrust Global CA" 证书。双击此条目以打开它的证书 window。
  7. 单击 "Details" 选项卡,然后单击 "Edit properties" 按钮。请注意 "Server Authentication," "Client Authentication," "Code Signing," "Secure Email," 和 "Time Stamping" 已被选中。
  8. 单击 "Disable all purposes for this certificate" 按钮。这将禁止使用此证书。在 "General" 选项卡上注意此证书的到期日期为 2022 年 5 月 20 日,并且 "Issued to:" 和 "Issued by:" 项目均已签名 "GeoTrust Global CA," 表明这是一个根证书。单击 "OK" 按钮 return 到 Windows 证书管理器。最小化证书管理器。
  9. 移至您的空白 https://www.google.com 网页。 刷新页面,然后查看证书。现在您将看到四个证书,而不是 SETP #3 中显示的三个证书!!
  10. 发生了什么事?双击 "GeoTrust Global CA" 证书。查看 "General" 选项卡上的到期日期。它是 8/20/2018,而不是步骤 #3 中为 "GeoTrust Global CA" 证书显示的 5/20/2022。还要查看 "Issued to:" 和 "Issued by:" 项 - 它们是不同的。 "Issued to:" 是 "GeoTrust Global CA" 并且 "Issued by" 是 "Equifax Secure Certificate Authority." 这是一个不同的 "GeoTrust Global CA" 证明在步骤 #3 中显示的那个!! 此版本的 "GeoTrust Global CA" 证书与 "Equifax Security Certificate Authority" 交叉根目录,如 "Issued by:" 项所示!!
  11. 双击 "GeoTrust" 根证书。请注意,这是 "Equifax Secure Certificate Authority." 颁发的自签名根证书,这是 https://www.google.com!! 使用的真实根证书 当我将此证书复制到我的 PHP .PEM 文件并用它来验证 https://www.google.com 的证书一切正常!!
  12. 返回 Windows 证书管理器并撤消您在步骤 5 - 8 中执行的禁用操作。单击 "Enable only the following purposes" 按钮并重新检查步骤 #7 中列出的用途。这会将日期为 2022 年 5 月 20 日的 "GeoTrust Global CA" 证书恢复到正常运行状态。

GeoTrust 网站上有一个 link 描述了步骤 #9 中出现的 "GeoTrust Global CA" 交叉根证书。您也可以下载它。但是,对于我的应用程序,交叉根证书没有验证 https://www.google.com 的证书 - 我需要使用 "GeoTrust" 根证书,因为它是唯一可以验证 https://www.google.com 的证书.这是 link:

https://knowledge.geotrust.com/support/knowledge-base/index?page=content&id=AR1426

您还可以从 GeoTrust 网站下载与 "GeoTrust" 证书等效的证书。它在网站的“资源”>“根证书”部分中列为 "Equifax Secure Certificate Authority"。这是 link:

https://www.geotrust.com/resources/root-certificates/

您还可以通过访问以下 Symantec 网页找到有关 任何 网页的证书链的更多详细信息:

https://cryptoreport.websecurity.symantec.com

希望这对需要验证与 Google.com 的 HTTPS 连接的 PHP 开发人员有所帮助。 DREW010 - 感谢您与我一起度过这个难关!感谢您的帮助。