Intereting Posts
Запрошенный URL / имя_проекта / пользователи не были найдены на этом сервере. Laravel Как я могу проверить форму POST, только содержит буквы в нескольких полях, используя preg_match? Как использовать самоподписанный сертификат с XAMPP для запросов HTTPS с использованием cURL? Как вставить новую пару ключевых значений в массив в php? Перенаправление URL с динамическим сегментом URI в cpanel Скачать файл с сайта PHP Я хочу обновить значение переключателя в базе данных (mysql), используя php Можно ли заблокировать файлы cookie с помощью Javascript или PHP? PHP – установка унаследованного статического свойства также установит его в других классах, наследующих его PHP – get_headers () возвращает неверный результат, если символы не UTF находятся в URL-адресе Подпись Версия 4 Процесс подписания в PHP для доступа к конечной точке шлюза API Страницы сохраняют обновление при использовании AJAX Вход в систему Opencart Force, когда вы видите страницу Cart? Doctrine2 Migration Использование DBAL вместо $ this-> addSql Нечетные разрешения для файла, измененного PHP move_uploaded_file ()

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

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

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

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

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

<?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 )

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

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

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

EDIT2: вы можете использовать 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('Ymd-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 read / write, и мне пришлось сделать его COM-вызываемым. Это изменение впервые доступно в версии v1.8.2.3 .

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

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

 <?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, чтобы запустить этот код … Надеюсь, эта заметка будет жесткой в ​​этом ответе «в ближайшее время»,

Вот как я это сделал. Это с превосходным, но это то же самое.

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

  • Доступ через веб-адрес retrieve.php? Codename = [кодовое имя]

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

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

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