文章目录

  1. 1. 引文:微信平台官方的公告
  2. 2. 缘起
  3. 3. 测试结果:
  4. 4. 查阅的文件

引文:微信平台官方的公告

公众平台调整SSL安全策略,请开发者注意升级

近一段时间HTTPS加密协议SSL曝出高危漏洞,可能导致网络中传输的数据被黑客监听,对用户信息、网络账号密码等安全构成威胁。为保证用户信息以及通信安全,微信公众平台将关闭掉SSLv2、SSLv3版本支持,不再支持部分使用SSLv2、 SSLv3或更低版本的客户端调用。请仍在使用这些版本的开发者于11月30日前尽快修复升级。

注意:通过微信开放平台(open.weixin.qq.com)进行移动应用和网页应用开发的开发者也同样需要修复升级。
建议开发者使用如下方法进行修复:
OpenSSL(http://www.openssl.org)可使用SSL_CTX SSL_CTX_new(const SSL_METHODmethod)函数设置SSL客户端请求方法,使用TLSv1_client_method或更高版本。

示例1(php):
curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);

示例2(C#):
System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12

微信团队
2014年10月29日


缘起

就这个安全策略的更改,让一堆人都比较茫然。
wechat-php-sdk类库的部分使用者和开发者们,也进行了讨论:
部分链接:pull#149pull#145issues#150

虽然查阅很多文件,最终认为应该为CURLOPT_SSLVERSION参数使用数值1,但毕竟微信官方的接口到11月30日后才会进行更改,才能得出结论。而查阅到的文件中都没有明确说TLS方式的值是1,心里总有些没底。因此今天查了查资料,自己做个模拟试验,来证明是否可用。

我的本地服务器端软件是phpStudy 2014版,集成的组件很多,我主要用Apache,而php有5.2-5.6共计5个版本。

思路:
1、使用Apache搭建https服务器
2、限制https服务器不允许使用SSLv2、SSLv3。也就是说只能用TLS方式了
这里就不说配置https的过程了,相关教程一堆。这里把最关键的关闭SSLv2、v3的内容说一下:
Apache的:
在httpd-ssl.conf文件中替换这两个设置:

1
2
SSLProtocol all -SSLv3 -SSLv2
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-RC4-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:ECDHE-RSA-AES128-SHA256:RC4-SHA:!aNULL:!eNULL:!EXPORT:!DES:!3DES:!MD5:!DSS:!PKS

这样就无法使用SSLv2、v3的方式连接https了,只能用TLS。
其他环境的请看文章最后的参考文章链接部分

使用的测试代码:
我将https的443端口指向的目录里有个1.php文件,内容很简单:

1
2
3
<?php
echo "yes!";
?>

然后是普通的http访问的页面http://127.0.0.1/99.php,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
function http_get($url){
$oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($oCurl, CURLOPT_SSLVERSION,1); //CURL_SSLVERSION_TLSv1
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
return $sContent;
}else{
return false;
}
}
$r=http_get("https://127.0.0.1/1.php");
var_dump($r);
exit;
?>

访问http页面:http://127.0.0.1/99.php
显示的结果是:

1
string(4) "yes!"

测试其他访问方式,修改99.php中 第7行的数值,进行测试。

1
2
3
4
5
6
7
8
9
CURLOPT_SSLVERSION 参数可选值的定义如下:
CURL_SSLVERSION_DEFAULT (0)
CURL_SSLVERSION_TLSv1 (1)
CURL_SSLVERSION_SSLv2 (2)
CURL_SSLVERSION_SSLv3 (3)
CURL_SSLVERSION_TLSv1_0 (4)
CURL_SSLVERSION_TLSv1_1 (5)
CURL_SSLVERSION_TLSv1_2 (6)
其中,后三种方式,在curl 7.34版以后才支持。

你可以发现,只要数值为2或3,都无法访问。而是用其他数值,根据php版本和curl版本不同,是否可以访问的结果也不同。


测试结果:

经过测试(本地搭建https服务器,限制只能用tls验证),HTTPS修改为tls验证方式后,通过设置参数
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1);
可以访问(不加也可以,会自动尝试TLS/SSL方式,但最好是加上)。

测试结果如下:
php版本5.2、5.3,curl版本为:7.21.0 只能用值1,即TLSv1
php版本5.4、5.5,curl版本:7.36.0 OpenSSL版本:0.9.8y/1.0.1f 可用值1或4,即TLSv1/v1.0
php版本5.6,curl版本:7.36.0 OpenSSL版本:1.0.1g 可用值1或4,即TLSv1/v1.0

或许是我服务器https配置问题,只能使用TLSv1.0访问,使用TLS的V1.1、V1.2版本会访问失败(即常量5、6)。

由此测试得出结论,国内无论用哪家的php空间,php版本至少达到5.2,curl版本为7.21及以上,使用常量值1即可(再低的我这没版本可以测试)。


查阅的文件

CURLOPT_SSLVERSION选项参考:http://php.net/manual/en/function.curl-setopt.php
apache下配置https的文档:http://flyli815.iteye.com/blog/1837204
http://csq-3.blog.163.com/blog/static/38738439200911741031190/
关闭apache下https的SSLv2、SSLv3访问设置:http://www.myhack58.com/Article/html/3/62/2014/54804_5.htm
其他:https://wiki.mozilla.org/Security/Server_Side_TLS

文章目录
  1. 1. 引文:微信平台官方的公告
  2. 2. 缘起
  3. 3. 测试结果:
  4. 4. 查阅的文件