ZipArchive avec chiffrement
Un petit point d'avancement du développement de l'extension zip version 1.14.0 qui intègre désormais le support des archives chiffrées.
L'implémentation de cette nouvelle fonctionnalité repose sur l'utilisation de la bibliothèque libzip version 1.2.0 récemment publiée.
Actuellement seule la compilation avec la bibliothèque système offre ce support, mais une mise à jour de la version embarquée est prévue.
Lorsque tout sera validé, la version sera publiée et intégrée aux sources de php (ext/zip), sans doute pour PHP 7.2.
il s'agit d'un développement en cours, rien n'est définitif, et les méthodes proposées peuvent encore changer.
Installation en RPM
Le paquet php-pecl-zip-1.4.0.0-0.2.20170301dev est disponible dans le dépôt remi-test (et remi-php70-test, remi-php71-test).
Installation depuis les sources
Depuis un clone des sources disponibles dans 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]
Création d'un archive chiffrée
Trois méthodes permettent de gérer le cryptage
ZipArchive::setEncryptionName($name, $method [, $password]); ZipArchive::setEncryptionIndex($index, $method [, $password]); ZipArchive::setPassword($password);
Le choix de la méthode de chiffrement devant être une des constantes ZipArchive::EM_NONE, ZipArchive::EM_AES_128, ZipArchive::EM_AES_192 ou ZipArchive::EM_AES_256.
Exemple 1 :
Mot de passe par fichier
$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();
Exemple 2 :
Mot de passe par defaut (global)
$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();
Lecture d'une archive chiffrée
Exemple :
$zip = new ZipArchive; $zip->open(__DIR__ . '/encrypted.zip'); print_r($zip->statName($file)); $zip->setPassword('secret'); $text = $zip->getFromName('foo.php'); $zip->close();
A noter :
- utilisation de la méthode setPassword qui positionne le mot de passe utilisé par défaut.
- la sortie de la méthode statName retourne une nouvelle information : encryption_method (259 pour ZipArchive::EM_AES_256)
Lecture d'un archive chiffrée via les flux
Il est nécessaire de passer le mot de passe en utilisant un context.
Exemple :
$ctx = stream_context_create(array( 'zip' => array( 'password' => 'secret' ) )); $text = file_get_contents('zip://' . __DIR__ . '/encrypted.zip#foo.php', false, $ctx);
Conclusion
Le script utilisé dans les exemples ci-dessus est disponible dans les sources de l'extension : encryption.php
Cette nouvelle fonctionnalité me semble très utile, et devrait offrir une meilleure compatibilité avec les outils existants, comme WinZip sous Windows ou 7za sous Linux.
Pour Fedora, cette évolution devrait être disponible dans Fedora 26 qui dispose déjà de libzip 1.2.0.