这是一个简单的 PHP 脚本,它打开一个准备发送 HTTP 请求的 SSL 套接字:
$contextOptions = 数组(); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); 出口; } var_dump($socket); exit('已创建套接字。');
这行得通——我刚刚对其进行了测试——但没有针对受信任的 CA 存储的验证。
我们可以修改该脚本以使用 PHP 的SSL 上下文选项:
$contextOptions = 数组( 'ssl' => 数组( 'cafile' => 'C:\xampp\cacerts.pem', 'CN_match' => '*.google.com', // 只有在 'verify_peer' 设置为 TRUE 时才会检查 CN_match。请参阅 https://bugs.php.net/bug.php?id=47030。 'verify_peer' => 真, ) ); $socketUrl = 'ssl://google.com:443'; $streamContext = stream_context_create($contextOptions); $socket = stream_socket_client($socketUrl, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $streamContext); if (!$socket || $errno !== 0) { var_dump($socket, $errstr); 出口; } var_dump($socket); exit('已创建套接字。');
只要“cafile”存在并且具有正确的 CA,那么这个例子也可以工作......
...但是我们如何在不对 CA 文件名/文件路径进行硬编码的情况下做到这一点?我们正在尝试创建独立于操作系统验证 SSL 证书的东西,而不需要为运行此脚本的每个服务器单独配置。
我知道 Linux 有一个 CA 目录,我们可以将其作为“capath”。窗户呢?它在哪里存储其受信任的 CA?我搜索了这些不幸的是似乎在注册表中,所以我们无法从 PHP 访问它们吗?其他操作系统呢?