Создайте зашифрованный zip-архив с помощью PHP


Я ищу способ зашифровать файл .txt в zip, но безопасным способом, защищенным паролем. Моя цель - отправить этот файл мне по электронной почте, чтобы никто не смог прочитать содержимое вложения.

Знает ли кто-нибудь простой и, прежде всего, безопасный способ сделать это? Я могу создавать zip-архивы, но я не знаю, как их зашифровать или насколько это безопасно.

Author: Dan McClain, 2009-03-14

5 answers

Примечание: в этом ответе рекомендуется использовать криптографический метод, который известен как небезопасный, даже с хорошим паролем. Пожалуйста, смотрите ссылку из комментариев и контроль качества Winzip на AES. Поддержка шифрования zip в php AES поставляется с php 7.2libzip 1.2.0), что означает, что этот ответ тоже скоро устареет. До тех пор смотрите этот ответ, чтобы узнать, как вызвать 7z вместо команды zip, которая поддерживает winzip AES шифрование.

Вы можете использовать это:

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

Где pass - это пароль, и file.txt будет застегнут на молнию в file.zip . Это должно работать в Windows и Linux, вам просто нужно получить бесплатную версию zip для Windows (http://www.info-zip.org/Zip.html#Win32 )

Этот вид безопасности может быть нарушен атаками грубой силы, атаками по словарю и т. Д. Но это не так просто, особенно если вы выбрали длинный и трудно угадываемый пароль.

 16
Author: fromvega, 2017-12-01 09:52:50

Начиная с php 7.2 (который был выпущен несколько часов назад), правильный способ сделать это - использовать дополнительные функции, включенные в ZipArchive собственный php-код. (спасибо абрахаму-тугалову за указание на то, что это изменение грядет)

Теперь простой ответ выглядит примерно так:

<?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";
}
?>

Но вы также можете задать метод шифрования по индексу, а не по имени, и вы можете установить каждый пароль для каждого файла... а также указать более слабые параметры шифрования, используя недавно поддерживаемые параметры шифрования.

В этом примере используются эти более сложные параметры.

<?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";
}
?>

Базовая поддержка шифрования zip включена, поскольку в libzip 1.2.0 появилась поддержка шифрования. Таким образом, вам понадобится php 7.2 и libzip 7.2, чтобы запустить этот код... Надеюсь, эта заметка будет посвящена этому ответу "очень скоро"

 6
Author: ftrotter, 2017-12-01 09:33:54

Хотя PHP является зрелым языком, не существует адекватного метода (исключая пользовательское расширение или что-то в этом роде) для решения такой простой задачи с помощью чистого PHP.
Что вы также можете сделать, так это подождать, пока PHP 7.2 не будет доступен для производства (потому что ZipArchive::setencryptionname будет реализован (благодаря Пьеру и Реми)).
Но до тех пор вы также можете попробовать перенести php_zip>=1.14.0 на PHP p.s. Я бы попробовал, но сейчас на моем компьютере нет VS2015+.

 4
Author: Abraham Tugalov, 2017-07-19 22:16:41

Все больше и больше инструментов поддерживают ZIP-файлы, зашифрованные AES. Это работает, это безопасно.

ПРАВКА 2: Вы можете использовать DotNetZip из PHP для динамического создания zip-архивов, зашифрованных AES, из PHP. DotNetZip - это библиотека .NET, предназначенная для языков .NET (C#, VB и т.д.). Он работает только в Windows:(. Но DotNetZip делает AES, и это бесплатно, и он работает с PHP.

Это код, который я использовал. (PHP v5.2.9 на Win32)

<?php
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>';
}

?>

Мне пришлось изменить DotNetZip, чтобы сделать он работает с PHP: Я должен был сделать свойство Name доступным для чтения/записи, и я должен был сделать его доступным для вызова. Это изменение впервые доступно в выпуске версии v1.8.2.3 .

 1
Author: Cheeso, 2009-03-29 21:45:22

Вот как я это сделал. Это с excel, но это одно и то же.

  • Позвольте php создать случайное кодовое имя.
  • Сохраните кодовое имя в БД или в файле, который будет включен retrieve.php .
  • Отправьте себе кодовое имя по почте.

  • Доступ через Интернет к файлу retrieve.php?кодовое имя=[кодовое имя]

  • Позвольте php проверить правильность кодового имени. (может быть, даже дело в возрасте).
  • Создайте excel/текстовый файл в памяти из данных, которые необходимо отправить в ты.
  • Создайте код шифрования, добавив локальный пароль (который знаете только вы) с кодовым именем.(Я говорю добавить, но также может быть смешан или изменен или изменен...)
  • Шифруйте на лету с помощью созданного кода шифрования.
  • Удалите кодовое имя из базы данных или конфигурационного файла.
  • Верните этот зашифрованный документ по почте (заархивированный или нет по размеру).
  • Возможно, добавьте два первых символа из кодового имени в почту, чтобы узнать, какое локальное полное кодовое имя использовать.

  • Используйте локальный сценарий расшифровки для декодирования загруженного файла. Используйте тот же алгоритм кодового имени/пароля для создания ключа расшифровки.

Я использую тарабарщину-aes-php. (https://github.com/ivantcholakov/gibberish-aes-php )
Потому что тогда я смогу использовать https://github.com/mdp/gibberish-aes как javascript на клиентском декодере (для вещей, которые я хочу быстро просмотреть в браузере).

 -2
Author: Joeri, 2014-01-01 22:04:43