2010-03-15 15 views
21

Próbuje napisać kilka funkcji, które będą szyfrowania i deszyfrowania plików i używam klasę znaleźć tutaj, aby spróbować osiągnąć ten cel:szyfrowania/odszyfrowania pliku z mcrypt

http://www.itnewb.com/v/PHP-Encryption-Decryption-Using-the-MCrypt-Library-libmcrypt

Funkcja szyfrowania poniżej wydaje do pracy, ponieważ wydaje się, że zaszyfrował plik i umieścił go w pożądanym katalogu. Próbuję odszyfrować plik teraz, i po prostu umiera z komunikatem "Nie udało się do końca odszyfrować" (który jest tam zakodowany ...) W dziennikach błędów php nie ma nic, więc nie jestem pewien, dlaczego to się nie udaje , ale jak mcrypt jest zupełnie nowe dla mnie, jestem bardziej niż skłonny uwierzyć, że robię coś złego tutaj ...

Oto funkcje:

//ENCRYPT FILE 
    function encryptFile() { 
     global $cryptastic; 
     $pass = PGPPASS; 
     $salt = PGPSALT; 
     $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key."); 

     if ($handle = opendir(PATH.'/ftpd')) { 
      while (false !== ($file = readdir($handle))) { 
       if ($file != "." && $file != "..") { 
        $newfile = PATH.'/encrypted/'.$file.'.txt'; 
        $msg = file_get_contents(PATH.'/ftpd/'.$file); 
        $encrypted = $cryptastic->encrypt($msg, $key) or die("Failed to complete encryption."); 
        $nfile = fopen($newfile, 'w'); 
        fwrite($nfile, $encrypted); 
        fclose($nfile); 
        unlink(PATH.'/ftpd/'.$file); 

       } 
      } 
      closedir($handle); 
     }  


//DECRYPT FILE 
    function inFTP() { 
     global $cryptastic; 
     $pass = PGPPASS; 
     $salt = PGPSALT; 
     $key = $cryptastic->pbkdf2($pass, $salt, 1000, 32) or die("Failed to generate secret key."); 

     if ($handle = opendir(PATH.'/encrypted')) { 
      while (false !== ($file = readdir($handle))) { 
       if ($file != "." && $file != "..") { 
        $newfile = PATH.'/decrypted/'.$file; 
        $msg = PATH.'/encrypted/'.$file; 
        $decrypted = $cryptastic->decrypt($msg, $key) or die("Failed to complete decryption."); 
        $nfile = fopen($newfile, 'w'); 
        fwrite($nfile, $decrypted); 
        fclose($nfile); 
        //unlink(PATH.'/encrypted/'.$file); 

       } 
      } 
      closedir($handle); 
     }  
     //$crypt->decrypt($file); 
    } 
+0

Czy klasa kryptograficzna nie ma jakiejś metody zgłaszania błędów, którą można wywołać? –

Odpowiedz

54

spróbować tej klasy PHP5 szyfrowania używając mcrypt. W tym przypadku używa szyfrowania AES. Będziesz chciał zmienić klucz dla każdej witryny, w której go używasz. Jeśli go nie użyjesz, przynajmniej może Ci pomóc w pisaniu własnej wersji.

<?php 

class Encryption 
{ 
    const CIPHER = MCRYPT_RIJNDAEL_128; // Rijndael-128 is AES 
    const MODE = MCRYPT_MODE_CBC; 

    /* Cryptographic key of length 16, 24 or 32. NOT a password! */ 
    private $key; 
    public function __construct($key) { 
     $this->key = $key; 
    } 

    public function encrypt($plaintext) { 
     $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); 
     $iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_URANDOM); 
     $ciphertext = mcrypt_encrypt(self::CIPHER, $this->key, $plaintext, self::MODE, $iv); 
     return base64_encode($iv.$ciphertext); 
    } 

    public function decrypt($ciphertext) { 
     $ciphertext = base64_decode($ciphertext); 
     $ivSize = mcrypt_get_iv_size(self::CIPHER, self::MODE); 
     if (strlen($ciphertext) < $ivSize) { 
      throw new Exception('Missing initialization vector'); 
     } 

     $iv = substr($ciphertext, 0, $ivSize); 
     $ciphertext = substr($ciphertext, $ivSize); 
     $plaintext = mcrypt_decrypt(self::CIPHER, $this->key, $ciphertext, self::MODE, $iv); 
     return rtrim($plaintext, "\0"); 
    } 
} 

Zastosowanie:

$key = /* CRYPTOGRAPHIC!!! key */; 
$crypt = new Encryption($key); 
$encrypted_string = $crypt->encrypt('this is a test'); 
$decrypted_string = $crypt->decrypt($encrypted_string); // this is a test 

Uwagi:

  • Ta klasa nie jest bezpieczny do stosowania z danych binarnych (które może zakończyć się NUL bajtów)
  • Ta klasa nie przewiduje uwierzytelnione szyfrowanie.
+3

Czy to działa w przypadku danych binarnych, takich jak obrazy? –

+3

Dla danych binarnych myślę, że musisz base64_encode go przed napisaniem –

+4

Zgadza się. Prowadziłem tę klasę w plikach tekstowych i działało świetnie. W przypadku plików binarnych konieczne jest zakodowanie informacji przed ich zaszyfrowaniem. Jeśli pliki są większe niż 100 MB, kod base64_encode spowoduje problemy z wydajnością, dlatego warto rozważyć podział plików na porcje w celu ich zaszyfrowania. Z punktu widzenia bezpieczeństwa nie jest to idealne rozwiązanie, ponieważ zapewnia więcej możliwości odzyskiwania częściowego tekstu jawnego. Ale działa. –

1

CakePHP ma całkiem niezłą odmianę implementation rijndael. Nie publikuję tutaj bezpośrednio kodu, ponieważ nie jestem pewien prawnych konsekwencji.

Here are the api docs dla metody Security::rijndael().

Jeśli kodowania pliku, będziemy chcieli, aby base64_encode() przed wywołaniem tej metody z „encrypt” i base64_decode() po wywołaniu tej metody z „decrypt

+0

base64_ * pracował dla mnie dla danych binarnych. Dzięki! – adela

2

Podczas Johns odpowiedź jest dobra, przy użyciu kodowania base64 tylko naprawić problem bezpieczeństwa binarnego jest przesadny i sprawi, że twoje zaszyfrowane pliki będą o 33% większe niż oryginał. Oto moja implementacja PHP w formacie pliku AES Crypt, który rozwiązuje wszystkie powyższe problemy w sposób przejrzysty.

https://github.com/philios33/PHP-AES-File-Encryption

Jest bezpieczny binarny i obejmuje uwierzytelnionego szyfrowania. Ponieważ używa formatu aes o otwartym kodzie źródłowym (.aes), jest w pełni kompatybilny z innym oprogramowaniem .aes.

https://www.aescrypt.com/

Interfejs jest bardzo prosty, czy szyfrowania lub deszyfrowania. Po prostu dajesz mu plik źródłowy i hasło.

1

Nie powinieneś używać Mcrypt do szyfrowania/odszyfrowywania danych. Jak pokazuje twoje pytanie, w zaakceptowanej odpowiedzi dane nie są uwierzytelniane, co oznacza, że ​​padną ofiarą wybranych ataków zaszyfrowanych tekstów.

Ponadto, podjęto wiele wysiłku, aby programiści prawidłowo ułożyli progi kryptograficzne. Jako takie, zamiast Mcrypt, powinieneś używać libsodium do swoich projektów PHP. libsodium jest widelcem NaCl. NaCl/libsodium został napisany w celu usunięcia wielu pułapek kryptograficznych, na jakie napotykają programiści, takich jak ataki czasowe z weryfikacją tagów MAC.

Mcrypt jest przestarzały w PHP 7.1, a libsodim jest preferowanym sposobem obsługi kryptografii w PHP.

Używanie libsodium w projekcie PHP jest łatwe i bezpieczne. Scott Arciszewski napisał obszerny ebook o używaniu libsodium z PHP pod numerem https://paragonie.com/book/pecl-libsodium. Warto przeczytać dla każdego, kto robi kryptografię PHP.