最终答案
如果您的 ISP 不会将 openSSL 升级到 TLS 1.2,您应该认真考虑其他 ISP。您应该使用下面的“SSL SERVER TEST”链接测试您的服务器。您的服务器可能存在 SSL 安全漏洞。
您尝试连接的服务器仅支持 TLS 1.2 和 TLS 1.1
不支持:TLS 1.0、SSL 3、SSL2。
当发出 SSL 请求时,作为 SSL 协议的一部分,curl 会向主机服务器显示一个密码列表。然后,服务器根据 curl 提供的列表选择要使用的密码协议。
您尝试联系的主机支持这些密码套件
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030)
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f)
TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 (0x9f)
TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 (0x9e)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 (0xc028)
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 (0x6b)
TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 (0xc027)
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 (0x67)
TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33)
TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d)
TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c)
TLS_RSA_WITH_AES_256_CBC_SHA256 (0x3d)
TLS_RSA_WITH_AES_256_CBC_SHA (0x35)
TLS_RSA_WITH_AES_128_CBC_SHA256 (0x3c)
TLS_RSA_WITH_AES_128_CBC_SHA (0x2f)
因为您的 openSSL 是在 2008 年 7 月发布的,而 TLSv1.2 是在下个月(2008 年 8 月)发布的,所以您最好的是 TLSv1.1
在升级之前可能会进行临时修复
我不太相信这对你有用
您应该使用类似 SSL SERVER TEST 的方式测试您自己服务器的 SSL
如果您的服务器支持 TLS1.1,那么您可以尝试以下方法。我无法对此进行测试,因为我在旧服务器上使用您的 openSSL 版本没有与您相同版本的 curl。
使用 curl 选项 CURLOPT_SSL_CIPHER_LIST 来限制主机服务器使用 TLS 1.1 以外的任何内容
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'TLSv1');
curl_setopt($ch, CURL_SSLVERSION_TLSv1_1);
如果没有,请尝试:
curl_setopt($ch, CURLOPT_SSL_CIPHER_LIST, 'DEFAULT');
curl_setopt($ch, CURL_SSLVERSION_TLSv1_1);
底线
除了这个问题之外,您需要升级您的 openSSL。
-------------------------------------------------------------------------
-
此前的故障排除低于此点
我要做的第一件事是关闭浏览器中的 javascript。如果我可以使用没有 javascript 的浏览器检索页面,我知道我可以使用 PHP 获取它。
我构建的请求看起来与浏览器中的完全一样。我转到检查器的网络选项卡并编辑请求标头并将其复制并粘贴到我的代码中。
$request = array();
$request[] = 'Host: example.com';
$request[] = 'Connection: keep-alive';
$request[] = 'Pragma: no-cache';
$request[] = 'Cache-Control: no-cache';
$request[] = 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8';
$request[] = 'User-Agent: Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36';
$request[] = 'DNT: 1';
$request[] = 'Origin: https://example.com';
$request[] = 'Referer: https://example.com/entry/login';
$request[] = 'Accept-Encoding: gzip, deflate';
$request[] = 'Accept-Language: en-US,en;q=0.8';
初始化卷曲
$url = 'https://example.com/entry/login';
$ch = curl_init($url);
添加请求参数
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
告诉 curl 包含标题
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, true);
返回响应
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
关注重定向
重定向可能是一个陷阱。您可能不必关注和分析响应。重定向通常用于设置 cookie。
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_COOKIESESSION , true );
让 curl 处理压缩
curl_setopt($ch, CURLOPT_ENCODING,"");
设置超时参数
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
发出请求并获得响应
以下内容将获得您需要了解的有关请求的所有信息。 $info 也将包含所有重定向标头。如果进行了重定向,则 $responseHeader 将包含所有响应标头。
更新:经过全面测试的新代码
这可能无关紧要,因为这也适用于我的机器:
echo file_get_contents($url);
如果 curl 失败,这段代码应该会告诉你失败的原因。
更改网址。这个属于客户。
<?php
header('content-type: text/plain');
$url = 'https://amxemr.com';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLINFO_HEADER_OUT, true);
curl_setopt($ch, CURLOPT_HEADER, true);
$data = curl_exec($ch);
if (curl_errno($ch)){
echo 'Retreive Base Page Error: ' . curl_error($ch);
}
else {
$info = rawurldecode(var_export(curl_getinfo($ch),true));
// Get the cookies:
$skip = intval(curl_getinfo($ch, CURLINFO_HEADER_SIZE));
$responseHeader= substr($data,0,$skip);
$data= substr($data,$skip);
echo "HEADER: $responseHeader\n";
echo "\n\nINFO: $info\n\nDATA: $data";
}
?>
如果上述方法不起作用,请运行 phpinfo()
<?php
phpinfo();
?>
应该有 curl 部分和 openSSL。
--------------------------------------------------------------------
更新二
好消息
我知道问题所在,并且能够复制您遇到的错误。
Retreive Base Page Error:
Unknown SSL protocol error in connection to www.xxxx.com:443
注意 xxx 是您提供给我的链接中的站点,您现在可以删除该消息。
有趣的是,我有一台服务器没有更新。幸运的是,它与 2008 年 7 月的 openSSL 版本相同。
您需要升级您的 openSSL。此服务器上的 file_get_contents() 也失败了。它适用于 2013 年 2 月版的 openSSL 以及 2014 年 6 月版。
我不能说是否需要升级其他任何东西,例如使用 openSSL 的功能可能(或可能不)需要升级。
我遵循格言,如果它没有坏就不要修复它。我确实相信一些升级实际上是降级。我还在XP。但它坏了,你需要修复它。
至少它不是在黑暗中修复的镜头。我相信你必须升级。这是一个有条不紊的故障排除程序,能够复制您的错误。您也可以重新使用file_get_contents()。