PHP和SSL CA验证-独立于操作系统


PHP and SSL CA Verification - OS Independent

下面是一个简单的PHP脚本,打开SSL套接字准备发送HTTP请求:

<>之前$contextOptions = array();$socketUrl = 'ssl://google.com:443';$streamContext = stream_context_create($contextOptions);$socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext);如果(!$socket || $errno !== 0) {var_dump(插座,errstr美元);退出;}美元var_dump(插座);退出('创建套接字。');之前

这个工作-我刚刚测试了它-但是没有针对可信CA存储的验证。

我们可以修改该脚本以使用PHP的SSL上下文选项:

<>之前$contextOptions = array('ssl' => array('cafile' => 'C:'xampp'cacerts.pem','CN_match' => '*.google.com',//只有当'verify_peer'设置为TRUE时才会检查CN_match。见https://bugs.php.net/bug.php?id=47030。'verify_peer' => TRUE,));$socketUrl = 'ssl://google.com:443';$streamContext = stream_context_create($contextOptions);$socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext);如果(!$socket || $errno !== 0) {var_dump(插座,errstr美元);退出;}美元var_dump(插座);退出('创建套接字。');之前

只要"cafile"存在并且有正确的CA,那么这个例子也可以工作…

…但是,如果不硬编码CA文件名/文件路径,我们如何做到这一点呢?我们正在尝试创建一些东西来验证SSL证书独立于操作系统,而不需要为运行该脚本的每个服务器单独配置。

我知道Linux有一个ca的目录,我们可以把它作为'capath'。Windows呢?它将其可信ca存储在哪里?我搜索和这些不幸似乎是在注册表,所以有没有办法我们可以从PHP访问它们?其他操作系统呢?

一场败仗…

在PHP 5.6之前,如果不手动设置"cafile""CN_match"上下文选项,就无法在PHP中进行安全加密传输。不幸的是,即使您正确设置了这些值,您的传输仍然很可能失败,因为5.6之前的版本在验证主机名时没有参考对等证书中日益流行的SAN (subjectAltName)扩展。因此,通过PHP内置的流包装器进行"安全"加密在很大程度上是一种用词不当。对于旧版本的PHP,最安全的选择是curl扩展。

关于windows证书…

Windows使用自己的证书存储,并以不同于OpenSSL的格式编码其证书。相比之下,openssl应用程序使用开放的. pem格式。5.6之前版本的PHP无法以任何方式与windows证书存储连接。因此,使用内置的流包装器功能在跨操作系统中进行可靠和安全的加密是不可能的。

PHP 5.6向前迈进了一大步

  • openssl。openssl。capath php.ini指令允许您全局分配证书位置,而无需在每个流上下文中设置它们

  • 所有加密流默认验证对等证书和主机名,如果没有提供"CN_match"上下文选项,则自动从URI解析主机名。

  • 流加密操作现在在验证主机名时检查对等证书SAN条目

  • 如果在流上下文 PHP .ini指令中没有指定CA文件/路径,PHP会自动返回到操作系统的证书存储库(在Windows中也是如此!)

作为一个例子,在PHP-5.6中,你需要做的就是安全地连接到github.com:

<?php
$socket = stream_socket_client("tls://github.com:443");

是的。真的是这样。不用担心上下文设置和验证参数。在这方面,PHP现在的功能与浏览器类似。

关于这个主题的更多阅读

这些PHP 5.6的变化只是SSL/TLS改进的冰山一角。我们努力使5.6成为迄今为止在加密通信方面最安全的PHP版本。

如果您想了解更多关于这些新功能的信息,可以通过官方渠道获得丰富的信息

  • [RFC]改进的TLS默认值
  • [RFC] TLS对等验证
  • 5.6新闻文件
  • 5.6升级文件

5.4/5.5中SAN匹配的注释

我们正在努力将至少与5.4和5.5分支匹配的SAN反向移植,因为如果没有这个功能,(作为客户端)将很难以任何有意义的方式使用加密包装器。虽然这个后台移植工作在很大程度上取决于我作为志愿者的空闲时间,但为这个答案投票肯定会帮助它更快实现:)