Search code examples
phppasswordsziparchivelibzip

Could not open password protected zip archive


I was creating a zip archive with php 7.4 (lib-zip version 1.6.1) without any problems.

Now I try to protect these zip archive with a password. Not just for encrypting with php, but in general. I found this tutorial. It does what it should, but I could not read the files of the zip archive any more. If I doubleclick on the archive, the password prompt opens up, but it does not work with the password from the source code. I also copy and pasted it to prevent any keyboard struggle.

<?php

$zip = new ZipArchive();
$filePath = sprintf('%s/test/', __DIR__);
$fileName = 'test.zip';
$absoluteFilePath = $filePath . $fileName;
$excludeFolderNames = [
  '.',
  '..',
  '.DS_Store',
  $fileName,
];

$zipFlag = ZipArchive::CREATE;
if (file_exists($absoluteFilePath)) {
    $zipFlag = ZipArchive::OVERWRITE;
}

$createFile = $zip->open($absoluteFilePath, $zipFlag);
if (true !== $createFile) {
    throw new RuntimeException(sprintf('could not open file in "%s" caused by %s', $fileName, $createFile));
}

$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($filePath));
$password = 'top-secret';
if (!$zip->setPassword($password)) {
    throw new RuntimeException('Set password failed');
}

/** @var SplFileInfo $value */
foreach ($iterator as $key => $value) {
    if (in_array($value->getFilename(), $excludeFolderNames)) {
        continue;
    }

    $cleanFilePath = realpath($key);
    if (!$cleanFilePath) {
        throw new RuntimeException(sprintf('could not create real path from filepath: %s', $key));
    }

    $zipName = str_replace($filePath, '', $cleanFilePath);
    if (!$zip->addFile($cleanFilePath, $zipName)) {
        throw new RuntimeException(sprintf('Add file failed: %s', $cleanFilePath));
    }

    if (!$zip->setEncryptionName($zipName, ZipArchive::EM_AES_256)) {
        throw new RuntimeException(sprintf('Set encryption failed: %s', $zipName));
    }
}

$zip->close();

Does someone has the same problem or am I the problem?

UPDATE I: I tought it solves my problem to save the zip-file outside the folder I want to zip. So I changed the following line:

$absoluteFilePath = sprintf('%s/%s', __DIR__, $fileName);

After a while the error occured again.

One possible reason I discovered, were .DS_Store files. In my example I exclude them. But the error occured again.

UPDATE II: One further problem is, that there is no password prompt, if all files are empty.

UPDATE III: Same code works with files without line break, but the error occurs, if the file has multiple lines.


Solution

  • I found help at the php-bugtracker. It turns out that I can extract all the files with an zip-extension like the comments tryed to tell me before. Now I wait for the new libzip version 1.7.0, where the default zip encryption is available. After this I hope I can extract my files without any extension.