前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从 PHP 函数报错看 HTTPS 与证书校验

从 PHP 函数报错看 HTTPS 与证书校验

作者头像
江不知
发布2022-04-12 15:13:44
1.4K0
发布2022-04-12 15:13:44
举报
文章被收录于专栏:编程拯救世界编程拯救世界

使用 PHP file_get_contents() 请求 HTTPS 资源,发生以下错误:

代码语言:javascript
复制
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 demo.php on line 79

错误显示:证书验证失败。证书验证发生在网络请求的哪个步骤?又为什么需要验证证书呢?一切要从 HTTPS 说起。

HTTPS 通信流程

HTTPS = HTTP + SSL,是在 HTTP 的基础上加上了 SSL 保护壳,信息的加密过程就是在 SSL 中完成的。它的通信流程如下:

HTTPS 通信流程

为什么需要验证证书?

HTTPS 通信流程中有一步「验证证书有效性」,证书是由受信任的 CA 机构颁布的,验证证书有效性可以确保你在和可信任的服务进行通信,避免第三方伪装的站点骗取你的信息。

如何验证证书?

首先,一个数字证书通常包含了以下信息:

  • 公钥
  • 持有者信息
  • 证书认证机构(CA)的信息
  • CA 对这份文件的数字签名及使用的算法
  • 证书有效期
  • ……

CA 在签发证书时,会将上述所有信息进行 Hash 计算,得到一个 Hash 值,我们在这称之为 Hash1。然后 CA 使用自己的私钥对该 Hash 值加密,生成 Certificate Signature(签名),将 Certificate Signature 添加到证书上,形成数字证书。

客户端在验证证书时,会使用同样的算法对证书信息进行 Hash 计算,得到 Hash2,并使用 CA 的公钥解出 Hash1。如果对比 Hash2 与 Hash1 相同,则证书可信,反之证书不可信。

CA 证书签名、校验过程

通常来说,浏览器和操作系统中集成了 CA 公钥信息。而我们此次 PHP 报错的原因,正是因为我们缺少了这个信息。

问题解决方法

下载 .pem 文件:https://curl.haxx.se/ca/cacert.pem

这个文件的内容就是「Bundle of CA Root Certificates」,即「根证书 CA 公钥集合」。

修改 php.ini,补充 cacert.pem 文件具体路径:

代码语言:javascript
复制
extension=php_openssl.dll
openssl.cafile=/home/disk1/file/cacert.pem

重启 PHP 服务后,问题得到解决。

绕过验证与绕过验证的风险

file_get_contents() 允许你通过传入 PHP SSL 上下文绕过 HTTPS 验证:

代码语言:javascript
复制
$arrContextOptions=array(
    "ssl" => array(
        "verify_peer" => false,
        "verify_peer_name" => false,
    ),
);
$content = file_get_contents($value['art_url'], false, stream_context_create($arrContextOptions));

但不建议在生产环境这么做,毕竟存在安全问题。

参考资料

  • 问题解决方法
    • file_get_contents SSL operation failed with code 1 SSL3_GET_SERVER_CERTIFICATE certificate verify failed[1]
    • PHP 配置文件修改[2]
  • `file_get_contents()` 函数介绍[3]
  • 浏览器如何验证HTTPS证书的合法性?[4]
  • What exactly is cacert.pem for?[5]

参考资料

[1]file_get_contents SSL operation failed with code 1 SSL3_GET_SERVER_CERTIFICATE certificate verify failed: http://www.bigsoft.co.uk/blog/2017/04/29/file-get-contents-ssl-operation-failed-with-code-1-ssl3-get-server-certificate-certificate-verify-failed

[2]PHP 配置文件修改: https://stackoverflow.com/questions/55526568/failed-loading-cafile-stream-in-file-get-contents

[3]file_get_contents() 函数介绍: https://www.php.net/manual/zh/function.file-get-contents.php

[4]浏览器如何验证HTTPS证书的合法性?: https://www.zhihu.com/question/37370216

[5]What exactly is cacert.pem for?: https://stackoverflow.com/questions/14987857/what-exactly-is-cacert-pem-for

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-03-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程拯救世界 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • HTTPS 通信流程
  • 为什么需要验证证书?
  • 如何验证证书?
  • 问题解决方法
  • 绕过验证与绕过验证的风险
  • 参考资料
    • 参考资料
    相关产品与服务
    SSL 证书
    腾讯云 SSL 证书(SSL Certificates)为您提供 SSL 证书的申请、管理、部署等服务,为您提供一站式 HTTPS 解决方案。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档