2009-03-14 15 views
18

Szukam sposobu szyfrowania pliku .txt w pliku ZIP, ale w sposób bezpieczny sposób chroniony hasłem. Moim celem jest przesłanie mi tego pliku e-mailem, bez konieczności czytania zawartości załącznika.Utwórz zaszyfrowane archiwum zip z PHP

Czy ktoś zna łatwy, a przede wszystkim bezpieczny sposób, aby to osiągnąć? Mogę tworzyć archiwa zip, ale nie wiem, jak je zaszyfrować, ani jak bezpieczne to jest.

Odpowiedz

17

Uwaga: ta odpowiedź zaleca metody kryptograficzne, który jest znany niepewny, nawet z dobrym hasłem. Proszę see link from comments i . Obsługa szyfrowania zip AES w postaci php przychodzi z php 7.2 (i libzip 1.2.0), co oznacza, że ​​ta odpowiedź będzie wkrótce również przestarzała. Do tego czasu see this answer for how to call out to 7z instead of the zip command, which supports winzip's AES encryption.

Można to wykorzystać:

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

Gdzie pass jest hasło i plik.txt zostaną spakowane do file.zip. To powinno działać w systemach Windows i Linux, wystarczy pobrać darmową wersję zip dla Windows (http://www.info-zip.org/Zip.html#Win32)

Tego rodzaju zabezpieczenia mogą zostać złamane przez brutalne ataki, ataki słownikowe itp. Ale to nie jest takie łatwe, specjalnie, jeśli wybrałeś długie i trudne do odgadnięcia hasło.

+0

dziękuję, spróbuję tego. to działa na serwerze linuxowym, więc dodatek nie będzie potrzebny. – Digits

+3

Szyfrowanie ZIP jest w rzeczywistości bardzo słabe, są ataki, które dają działające hasło (jeśli niekoniecznie to samo hasło, które było pierwotnie używane) w stosunkowo krótkim czasie. – bobince

+3

Ta odpowiedź jest czynnie niebezpieczna. Szyfrowanie używane przez tę odpowiedź jest straszliwie słabe. Jest to * nie * nowoczesne szyfrowanie oparte na AES. –

1

Coraz więcej narzędzi obsługuje pliki ZIP z szyfrowaniem AES. Działa, jest bezpieczny.

EDIT2: Możesz użyć DotNetZip z PHP, aby dynamicznie generować archiwa zip szyfrowane AES z PHP. DotNetZip to biblioteka .NET zaprojektowana dla języków .NET (C#, VB itp.). To działa tylko na Windows :(. Ale DotNetZip robi AES, i to za darmo i działa z PHP.

Jest to kod użyłem. (PHP v5.2.9 na 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>'; 
} 

?> 

I musiałem zmodyfikować DotNetZip, aby działało z PHP: musiałem wprowadzić właściwość Name do odczytu/zapisu i musiałem ją ustawić jako COM. Zmiana ta jest najpierw dostępna w v1.8.2.3 release.

+0

i czy wiesz, jak mogę tego użyć w skrypcie php? Wielkie dzięki! – Digits

+1

jeśli używasz PHP w systemie Windows, istnieje DotNetZip (http://dotnetzip.codeplex.com), który obsługuje szyfrowane zamki AES. PHP może wywoływać komponenty .NET. badda bing, badda boom. – Cheeso

+1

Niestety większość moich serwerów działa na Linuksie. ale mogę użyć tego rozwiązania dla tych w Windows. Dziękuję Ci bardzo! – Digits

-1

Tak właśnie zrobiłem Jest z excelem, ale to samo.

  • Pozwól php utworzyć losową nazwę kodową.
  • Zapisz nazwę kodową w db lub w pliku, który ma być dołączony przez retrieve.php.
  • Wyślij wiadomość e-mail z kryptonimem.

  • Dostęp przez WWW retrieve.php? Ps = [ps]

  • Niech czek php jeśli nazwa kodowa jest poprawna. (może nawet w tym wieku).
  • Utwórz excel/textfile w pamięci z danych, które należy wysłać do ciebie.
  • Utwórz kod szyfrujący, dodając lokalne hasło (które znasz tylko) z kryptonimem. (Mówię, że dodasz, ale możesz też mieszać, xor-ed lub substr ...)
  • Szyfruj w locie z utworzonym kodem szyfrowania.
  • Usunięcie nazwy kodowej z db lub pliku konfiguracyjnego.
  • Zwróć ten zaszyfrowany dokument pocztą (zip lub nie).
  • Może dodać dwa pierwsze znaki z kryptonimu w mailu, aby wiedzieć, jaki lokalny jest pełny kod.

  • Użyj lokalnego skryptu deszyfrującego, aby zdekodować pobrany plik. Użyj tego samego algorytmu kodu/hasła, aby utworzyć klucz deszyfrowania.

Używam gibberish-aes-php. (https://github.com/ivantcholakov/gibberish-aes-php) Ponieważ wtedy mogę użyć https://github.com/mdp/gibberish-aes jako javascript na dekoderze klienta (dla rzeczy, które chcę zrobić szybki podgląd w przeglądarce).

3

Chociaż PHP jest dojrzałym językiem, nie ma odpowiedniej metody (z wyjątkiem niestandardowego rozszerzenia lub czegoś podobnego), aby osiągnąć tak proste zadanie z czystym PHP.
Co możesz zrobić, to poczekać, aż PHP 7.2 będzie dostępny do produkcji (bo ZipArchive::setEncryptionName jest zaimplementowany (dzięki Pierre i Remi)).
Ale do tego czasu możesz także spróbować przesłać php_zip> = 1.14.0 do PHP 7.2, ale obecnie nie ma dostępnych skompilowanych plików binarnych, więc musisz sam je skompilować i spróbować, czy jest to w ogóle możliwe (wierzę to jest).
p.s. Spróbowałbym, ale nie mam VS2015 + na moim komputerze teraz.

0

Od wersji 7.2 (która została wydana przed kilkoma godzinami), właściwym sposobem jest użycie dodatkowej funkcjonalności zawartej w natywnym kodzie php ZipArchive. (Dzięki abraham-tugalov za wskazanie, że zmiana ta nadchodzi)

Teraz prosta odpowiedź wygląda mniej więcej tak:

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

Ale można też ustawić metodę szyfrowania przez indeks, a nie imię i nazwisko, i można ustaw każde hasło dla każdego pliku ... oraz określ słabsze opcje szyfrowania, korzystając z tego przykładu, aby wykonać te bardziej złożone opcje.

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

Podstawowym wsparcie dla szyfrowania zip jest włączona ponieważ libzip 1.2.0 wprowadzono wsparcie dla szyfrowania. Musisz więc mieć php 7.2 i libzip 7.2, aby uruchomić ten kod ... Mam nadzieję, że ta uwaga będzie bezpodstawna w tej odpowiedzi "wkrótce"

Powiązane problemy