是否可以使用流上下文在PHP下使用FTPS?

时间:2014-02-18 12:33:56

标签: php security ssl ftp ftps

我了解到在PHP for Windows下使用 ftps ('ftp_ssl_connect()')很难。您被要求进入构建自己的二进制文件以包含Open SSL的漫长旅程...我在phpseclib上找到了建议作为替代(但是获得openssl.cnf支持同行验证的权利对我来说也很难...)。

然后我点击this article,其令人愉快的简单示例包括工作对等验证(以避免中间人攻击)引起我对流的关注:

$uri = 'https://www.bankofamerica.com/';
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => true, // important
    'cafile' => '/hard/path/to/cacert.pem',
    'CN_match' => 'www.bankofamerica.com'
]]);
$html = file_get_contents($uri, FALSE, $ctx); // we are good

但是,这对ftp连接有用吗? 我是否也可以使用经过对等验证的流上下文来打开ftps流? The php manual hints,ssl上下文选项也适用于sftp,但缺乏进一步的指导。

所以我疯狂地猜测:

$ctx = stream_context_create(['ftps' => [
    'verify_peer' => true,
    'cafile' => 'd:/sandbox/mycerts.pem',
    'CN_match' => 'ftp-12345678.mywebhoster.com'
]]);

右?错误?用户+密码现在作为选项?然后什么?用户/密码呢?还是以后?我很无能......

  • 如何扫描远程ftp目录内容?
  • 如何从ftp服务器上传或下载文件?

这有可能吗? (几行代码会非常有用......)或者流是否仅适用于单个文件访问?

更新: Curl可能会做我想要的(包括对等验证和目录lsiting)as shown in this SO answer。将在本周晚些时候进行检查......

1 个答案:

答案 0 :(得分:13)

这会起作用吗?

  

我还可以使用经过对等验证的流上下文来打开ftps流吗?

是。 ftps 流包装器使用与 https 包装器相同的SSL上下文选项,只要您在PHP版本中启用了openssl扩展,它就可用。您可以通过检查stream_get_wrappers()的输出来验证 ftps 包装是否可用:

<?php
print_r(stream_get_wrappers());

如果你在php版本中启用了ext / openssl,你会看到输出中列出的 ftps 以及其他可用的流包装器。

如何分配SSL上下文选项?

  

所以我疯狂地猜测

你真的很亲密!您需要更改代码的唯一方法是将"ftps"替换为"ssl",如下所示:

<?php
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => true,
    'cafile' => 'd:/sandbox/mycerts.pem',
    'CN_match' => 'ftp-12345678.mywebhoster.com'
]]);

无论您是使用 https ftps 还是任何其他流包装器,管理SSL / TLS加密的上下文选项始终存储在"ssl"中键。

我在哪里放置用户/密码?

  

右?错误?用户+密码现在作为选项?然后什么?用户/密码呢?还是以后?我很无能......

ftp ftps 流包装器都需要URI中的用户名和密码,如下所示:

<?php
$ftpPath = 'ftps://username:password@example.com';

不要被我们的用户规范/明确的密码错误抛弃。在建立加密连接后,流包装器将仅发送用户名和密码

全部放在一起

opendir()系列函数支持 ftp 包装器(自PHP 5.0起)。您可以像使用本地文件系统路径一样使用这些函数:

<?php
$ctx = stream_context_create(['ssl' => [
    'verify_peer' => true,
    'cafile' => 'd:/sandbox/mycerts.pem',
    'CN_match' => 'ftp-12345678.mywebhoster.com'
]]);
$dirHandle = opendir('ftps://username:password@example.com/', $ctx);
while (($file = readdir($dirHandle)) !== false) {
    echo "filename: $file\n";
}
closedir($dirHandle);

关于SSL / TLS名称匹配的注意事项

如果它最初不起作用,您应该在不传递包含SSL选项的附加上下文$ctx的情况下进行测试。服务器证书的CN(公用名)字段必须与您指定的"CN_match"值匹配(子域的通配符匹配有限)。此外,在即将发布的PHP-5.6版本之前,不支持将名称与远程方证书中的“使用者备用名称”字段进行匹配。除非您正在使用5.6的开发预览,否则您将无法使用此功能(SAN匹配),如果服务器依赖SAN,则对等验证例程将失败。