Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create an encrypted zip archive with PHP

I am searching for a way to encrypt a .txt file into a zip, but in a secure password protected way. My goal is to email this file to me, without anyone being able to read the content of the attachment.

Does anybody know an easy, and above all, secure way to accomplish this ? I can create zip archives, but I do not know how to encrypt them, or, how secure this is.

like image 708
Digits Avatar asked Mar 14 '09 16:03

Digits


People also ask

Can we encrypt zip file?

Password protect a zip file (Windows 10 and macOS)Open WinZip and click Encrypt in the Actions pane. Enter a secure password when the dialog box appears. Click OK. Click the Options tab in the Actions pane and choose Encryption Settings.

How do I encrypt a zip file with 7zip?

From the "Archive format" field, select zip. Under the "Encryption" section, enter a strong password or passphrase in the "Enter passphrase" field and again in the "Reenter passphrase" field. Ensure the "Encryption method" is AES-256. Onced finished, click OK.


2 Answers

As of php 7.2 (which was released a hours ago), the right way to do this is to use additional functionality included in ZipArchive native php code. (thanks to abraham-tugalov for pointing out that this change was coming)

Now the simple answer looks something like this:

<?php $zip = new ZipArchive(); if ($zip->open('test.zip', ZipArchive::CREATE) === TRUE) {     $zip->setPassword('secret_used_as_default_for_all_files'); //set default password      $zip->addFile('thing1.txt'); //add file     $zip->setEncryptionName('thing1.txt', ZipArchive::EM_AES_256); //encrypt it      $zip->addFile('thing2.txt'); //add file     $zip->setEncryptionName('thing2.txt', ZipArchive::EM_AES_256); //encrypt it      $zip->close();      echo "Added thing1 and thing2 with the same password\n"; } else {     echo "KO\n"; } ?> 

But you can also set the encryption method by index and not name, and you can set each password on a per-file basis... as well as specify weaker encryption options, using the newly supported encryption options.

This example exercises these more complex options.

<?php $zip = new ZipArchive(); if ($zip->open('test.zip', ZipArchive::CREATE) === TRUE) {       //being here means that we were able to create the file..       //setting this means that we do not need to pass in a password to every file, this will be the default     $zip->addFile('thing3.txt');      //$zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_128);     //$zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_192);     //you should just use ZipArchive::EM_AES_256 unless you have super-good reason why not.      $zip->setEncryptionName('thing3.txt', ZipArchive::EM_AES_256, 'password_for_thing3');       $zip->addFile('thing4.txt');     //or you can also use the index (starting at 0) of the file...     //which means the following line should do the same thing...     //but just referencing the text.txt by index instead of name..     //$zip->setEncryptionIndex(1, ZipArchive::EM_AES_256, 'password_for_thing_4'); //encrypt thing4, using its index instead of its name...      $zip->close();     echo "Added thing3 and thing4 with two different passwords\n"; } else {     echo "KO\n"; } ?> 

The underlying support for zip encryption is enabled because libzip 1.2.0 introduced support for encryption. So you will need to have php 7.2 and libzip 7.2 in order to run this code... Hopefully this note will be cruft on this answer "real soon"

like image 180
ftrotter Avatar answered Oct 23 '22 21:10

ftrotter


Note: this answer recommends a cryptographic method that is known insecure, even with good password. Please see link from comments and the Winzip QA on AES. Support for in-php AES zip encryption arrives with php 7.2 (and libzip 1.2.0), which means this answer will soon be outdated too. Until then see this answer for how to call out to 7z instead of the zip command, which supports winzip's AES encryption.

You can use this:

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

Where pass is the password, and file.txt will be zipped into file.zip. This should work on Windows and Linux, you just need to get a free version of zip for Windows ( http://www.info-zip.org/Zip.html#Win32 )

This kind of security can be broken by brute force attacks, dictionary attacks and etc. But it's not that easy, specially if you chose a long and hard to guess password.

like image 31
fromvega Avatar answered Oct 23 '22 21:10

fromvega