简体   繁体   中英

How to create password protected archive file in PHP?

I need to be able to create an archive(zip) file with password protection using PHP. I am using Laravel 5.4 and PHP 7.1 version. I looked at this link here for ZipArchive class documentation in PHP. I also looked at here for setPassword function. But appears that creation of password protected archives is not supported. It will be a massive surprise for me if it is not possible to create password protected archive in a mature programming language such as PHP 7.1.

So I guess I must be missing something. Can someone point me to the right direction? Eg a sample example or open source third party library or extension to achieve this will be greatly appreciated.

Easy peasy lemon squeezy (no).
Yes, creation of password protected archives is not supported (they will be created simply as non-protected archives, as you just described).
But, still it can be used to extract password protected archives.

Returning to the problem.
You always can just

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

(this will work both on Windows and our beloved Linux)

But, if it not fits into your requirements, let's continue.
I would suggest you to use DotNetZip (Windows only), you will exactly dynamically generate AES-encrypted zip archives from 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>';
}

?>

But still, this is very dirty solution and more of that, not works on Linux.

So , although PHP is a mature language, there is no adequate method (excluding custom extension or something like that) to achieve such a simple task with pure PHP.
What you also can do, is to wait until PHP 7.2 will be available for production (cuz ZipArchive::setEncryptionName is implemented (thanks to Pierre and Remi)).
But, until then you also can try to port php_zip >= 1.14.0 to PHP < 7.2, but there is currently no compiled binaries available, so you have to compile it yourself and try if it is possible at all (I believe it is).
ps I would try it, but have no VS2015+ on my PC right now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM