因为微信支付的HTTPS服务器证书升级,所以得安装DigiCert的根CA证书,我的系统是 CentOs,按照微信给出的方案是
安装根证书管理包软件: yum install ca-certificates
打开根证书动态配置开关: update-ca-trust force-enable
将DigiCert的根证书文件复制到: /etc/pki/ca-trust/source/anchors/
安装根证书: update-ca-trust extract
(更多的命令行参数及说明, 请查看: man update-ca-trust)
安装完成后,测试微信给出的测试地址,没问题。但是线上服务挂了。报错如下
PHP Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages:
error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed in /var/www/html/test/test.php on line 4
PHP Warning: file_get_contents(): Failed to enable crypto in /var/www/html/test/test.php on line 4
PHP Warning: file_get_contents(https://api.weixin.qq.com/sns/jscode2session?appid=wxe8776ea4&secret=5ae4d6d4076502506c8&js_code=011phsMr0BSGQd1AqxKr0K9jMr0phsMq&grant_type=authorization_code): failed to open stream: operation failed in /var/www/html/test/test.php on line 4
先说我的问题的解决方案:更新 OpenSSL 到最新版
下面是寻找问题解决方案的过程
百度到一篇文章是这样说的(百度出来的都一样,大家都是互相抄的,有些是网站自动爬的,太他妈恶心了)
说是本地 CA 证书太旧,要更新
CentOs 可以用下面的命令更新
update-ca-trust
结果不管用,因为CA证书本来就是最新的了,再看看这个命令还有其他什么用法
update-ca-trust -h #什么都没有输出
update-ca-trust --help #什么都没有输出
继续 man update-ca-trust ,啥也看不懂
百度这个命令,基本没什么资料,有几篇文章的大概内容是这样的
https://techjourney.net/update-add-ca-certificates-bundle-in-redhat-centos/
里面提到了几个参数,基本跟微信上说的一样
update-ca-trust check #没反应
update-ca-trust enable #没反应
update-ca-trust extract #没反应
都没有结果,然后查看 update-ca-trust 这个文件,内容如下
红框内的内容大概是“本脚本目前会忽略一切参数,未来的版本会支持 extract ”,确实也没看到任何接收参数的代码,也不知道网上那些命令的参数都哪里来的,包括微信官方给出的方法竟然也是一样的。
将证书下载到 /etc/pki/ca-trust/source/anchors/ ,然后 update-ca-trust,
查看证书
awk -v cmd='openssl x509 -noout -subject' '/BEGIN/{close(cmd)};{print | cmd}' < /etc/pki/tls/certs/ca-bundle.crt
结果已经支持 GeoTrust ,但是仍然报上面的错。
网上有说法,修改 php.ini 文件,指定 OpenSSL的证书和证书搜索目录,百度一大堆,都是一样的,也不知道他们解决了没。找到 php.ini 中的配置如下
这两个配置的注释中都说了,大部分用户都不用修改这两个配置,PHP会自动搜索系统管理的证书。那看看都去哪里搜索了。
php -r "print_r(openssl_get_cert_locations());"
结果如下,没毛病
/etc/pki/tls/cert.pem 这个文件中看到了 GeoTrust 证书,基本可以确定不是这个问题。
兜兜转转一天过去了,没解决问题,再回过头来看看最初的错误,前面有说本地 CA 太旧导致的证书无法验证,很明显,我本地的 CA 证书是刚更新的,那有没有可能是OpenSSL版本太老,没法识别新的证书呢,试试吧
查看当前OpenSSL版本
openssl version
确定是不是用 yum 安装的
yum list installed |grep openssl
当前版本是 1.0.1,2013年的包,好像之前在网上看到 ca-certificate 2017什么的,所以先更新一下吧
yum -y update openssl
更新后的版本截图
更新完后立刻就测试了一下,发现没有问题了。
在网上也看到了一篇提到了OpenSSL太老导致这个问题,那篇文章写的太简单了,只是提到了一嘴,就没发现,回头整理的时候才发现有这么一句。贴上地址
http://blog.sina.com.cn/s/blog_54ef39890102wjz0.html
一篇不错的问答
https://serverfault.com/questions/394815/how-to-update-curl-ca-bundle-on-redhat
———完