Как создать защищенный паролем архивный файл в PHP?


Мне нужно иметь возможность создать архивный (zip) файл с защитой паролем с помощью PHP. Я использую версию Laravel 5.4 и PHP 7.1. Я посмотрел по этой ссылке здесь для документации класса ZipArchive на PHP. Я также посмотрел здесь для функции SetPassword. Но похоже, что создание защищенных паролем архивов не поддерживается. Для меня будет большим сюрпризом, если невозможно создать защищенный паролем архив на таком зрелом языке программирования, как PHP 7.1.

Так что, наверное, я что-то упускаю. Может ли кто-нибудь указать мне правильное направление? например, мы будем очень признательны за пример или стороннюю библиотеку с открытым исходным кодом или расширение для достижения этой цели.

Author: Andy, 2017-07-19

1 answers

Легкий лимонный сок (нет).
Да, создание защищенных паролем архивов не поддерживается (они будут созданы просто как незащищенные архивы, как вы только что описали).
Но, тем не менее, его можно использовать для извлечения защищенных паролем архивов.

Возвращаясь к проблеме.
Вы всегда можете просто

<?php echo system('zip -P pass file.zip file.txt'); ?>

(это будет работать как в Windows, так и в нашем любимом Linux)

Но, если это не соответствует вашим требованиям, давайте продолжим.
Я бы посоветовал вам используйте DotNetZip (только для Windows), вы будете точно динамически генерировать zip-архивы, зашифрованные AES, из PHP.

<?php
// origin: https://stackoverflow.com/a/670804/3684575
try
{
  $fname = "zip-generated-from-php-" . date('Y-m-d-His') . ".zip";
  $zipOutput = "c:\\temp\\" . $fname;
  $zipfact = new COM("Ionic.Zip.ZipFile");
  $zip->Name = $zipOutput;
  $dirToZip= "c:\\temp\\psh";
  # Encryption:  3 => 256-bit AES.  
  #     2 => 128-bit AES.  
  #     1 => PKZIP (Weak).  
  #     0 => None
  $zip->Encryption = 3;
  $zip->Password = "AES-Encryption-Is-Secure";
  $zip->AddDirectory($dirToZip);
  $zip->Save();
  $zip->Dispose();

  if (file_exists($zipOutput))
  {
    header('Cache-Control: no-cache, must-revalidate');
    header('Content-Type: application/x-zip'); 
    header('Content-Disposition: attachment; filename=' . $fname);
    header('Content-Length: ' . filesize($zipOutput));
    readfile($zipOutput);
    unlink($zipOutput);
  }
  else 
  {
    echo '<html>';
    echo '  <head>';
    echo '  <title>Calling DotNetZip from PHP through COM</title>';
    echo '  <link rel="stylesheet" href="basic.css"/>';
    echo '  </head>';
    echo '<body>';
    echo '<h2>Whoops!</h2>' . "<br/>\n";
    echo '<p>The file was not successfully generated.</p>';
    echo '</body>';
    echo '</html>';
  } 
}
catch (Exception $e) 
{
    echo '<html>';
    echo '  <head>';
    echo '  <title>Calling DotNetZip from PHP through COM</title>';
    echo '  <link rel="stylesheet" href="basic.css"/>';
    echo '  </head>';
    echo '<body>';
    echo '<h2>Whoops!</h2>' . "<br/>\n";
    echo '<p>The file was not successfully generated.</p>';
    echo '<p>Caught exception: ',  $e->getMessage(), '</p>', "\n";
    echo '<pre>';
    echo $e->getTraceAsString(), "\n";
    echo '</pre>';
    echo '</body>';
    echo '</html>';
}

?>

Но все же, это очень грязное решение, и более того, оно не работает в Linux.

Таким образом, , хотя PHP является зрелым языком, не существует адекватного метода (исключая пользовательское расширение или что-то в этом роде) для решения такой простой задачи с помощью чистого PHP.
Что вы также можете сделать, так это подождать, пока PHP 7.2 будет доступен для производство (потому что ZipArchive::setencryptionname реализован (благодаря Пьеру и Реми)).
Но до тех пор вы также можете попробовать перенести php_zip>=1.14.0 на PHP p.s. Я бы попробовал, но сейчас на моем компьютере нет VS2015+.

 4
Author: Abraham Tugalov, 2017-07-19 22:15:28