ZipArchive with encryption
+
Par Remi le mercredi 1 mars 2017, 11:16 - Développement - Lien permanent
Point of the situation with the development of zip extension version 1.14.0 which implements support of encrypted archives.
This new feature implementation rely on libzip library new version 1.2.0.
For now, only build using system library is supported for this new feature, but an update of the bundled library is planed.
When everything will be validated, version will be released and merged in php sources (ext/zip), probably in PHP 7.2.
this development is in progress, nothing final, proposed methods still can change.
RPM installation
The php-pecl-zip-1.4.0.0-0.2.20170301dev package is available in remi-test repository (and remi-php70-test, remi-php71-test).
Installation from sources
From a clone of the sources, available in github :
$ phpize $ ./configure --with-libzip ... checking for libzip... from pkgconfig: version 1.2.0 found in /usr/lib64 checking for zip_open in -lzip... yes checking for zip_file_set_encryption in -lzip... yes ... $ make ... Build complete. Don't forget to run 'make test'. $ make test ... PASS ZipArchive::setEncryption*() functions [tests/oo_encryption.phpt]
Encrypted archive creation
Three methods are available to manage encryption :
ZipArchive::setEncryptionName($name, $method [, $password]); ZipArchive::setEncryptionIndex($index, $method [, $password]); ZipArchive::setPassword($password);
Encryption method being one of the new constants: ZipArchive::EM_NONE, ZipArchive::EM_AES_128, ZipArchive::EM_AES_192 or ZipArchive::EM_AES_256.
Example 1:
Using per file password
$zip = new ZipArchive; $zip->open(__DIR__ . '/encrypted.zip', ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE); $zip->addFile(__FILE__, 'foo.php'); $zip->setEncryptionName('foo.php', ZipArchive::EM_AES_256, 'secret'); $zip->close();
Example 2:
Using default (global) password
$zip = new ZipArchive; $zip->open(__DIR__ . '/encrypted.zip', ZIPARCHIVE::CREATE | ZipArchive::OVERWRITE); $zip->setPassword('secret'); $zip->addFile(__FILE__, 'foo.php'); $zip->setEncryptionName('foo.php', ZipArchive::EM_AES_256); $zip->close();
Encrypted archive reading
Example :
$zip = new ZipArchive; $zip->open(__DIR__ . '/encrypted.zip'); print_r($zip->statName($file)); $zip->setPassword('secret'); $text = $zip->getFromName('foo.php'); $zip->close();
To be noticed :
- the setPassword method call, which set the default password
- the statName method output now includes a new information field: encryption_method (259 is ZipArchive::EM_AES_256)
Encrypted archive reading using stream
The password need to be given using a stream context.
Exemple :
$ctx = stream_context_create(array( 'zip' => array( 'password' => 'secret' ) )); $text = file_get_contents('zip://' . __DIR__ . '/encrypted.zip#foo.php', false, $ctx);
Conclusion
Full script used in above examples is available in the extension sources: encryption.php
This new feature seems really useful and will improve compatibility with other tools, such as WinZip for Windows or 7za for Linux.
This change should be available in Fedora 26 which already have libzip 1.2.0.
Commentaires
Code already available in php master (aka 7.2), only waiting for someone to update bundled libzip.