我了解到在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'
]]);
右?错误?用户+密码现在作为选项?然后什么?用户/密码呢?还是以后?我很无能......
这有可能吗? (几行代码会非常有用......)或者流是否仅适用于单个文件访问?
更新: Curl可能会做我想要的(包括对等验证和目录lsiting)as shown in this SO answer。将在本周晚些时候进行检查......
答案 0 :(得分:13)
我还可以使用经过对等验证的流上下文来打开ftps流吗?
是。 ftps 流包装器使用与 https 包装器相同的SSL上下文选项,只要您在PHP版本中启用了openssl扩展,它就可用。您可以通过检查stream_get_wrappers()
的输出来验证 ftps 包装是否可用:
<?php
print_r(stream_get_wrappers());
如果你在php版本中启用了ext / openssl,你会看到输出中列出的 ftps 以及其他可用的流包装器。
所以我疯狂地猜测
你真的很亲密!您需要更改代码的唯一方法是将"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选项的附加上下文$ctx
的情况下进行测试。服务器证书的CN(公用名)字段必须与您指定的"CN_match"
值匹配(子域的通配符匹配有限)。此外,在即将发布的PHP-5.6版本之前,不支持将名称与远程方证书中的“使用者备用名称”字段进行匹配。除非您正在使用5.6的开发预览,否则您将无法使用此功能(SAN匹配),如果服务器依赖SAN,则对等验证例程将失败。