Я ищу способ зашифровать файл .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, чтобы запустить этот код … Надеюсь, эта заметка будет жесткой в этом ответе «в ближайшее время»,
Вот как я это сделал. Это с превосходным, но это то же самое.
Напишите себе кодовое имя.
Доступ через веб-адрес retrieve.php? Codename = [кодовое имя]
Возможно, добавьте два первых символа из кодового имени в почте, чтобы узнать, какое локальное полное кодовое имя использовать.
Используйте локальный скрипт дешифрования для декодирования загруженного файла. Используйте один и тот же алгоритм имен кодов / паролей для создания ключа дешифрования.
Я использую gibberish-aes-php. ( https://github.com/ivantcholakov/gibberish-aes-php )
Потому что тогда я могу использовать https://github.com/mdp/gibberish-aes как javascript на клиентском декодере (для вещей, которые я хочу быстро заглянуть в браузер).