Подтвердить что ты не робот

Шифрование/дешифрование файла с помощью Mcrypt

Попытка написать пару функций, которые будут шифровать или дешифровать файл, и я использую класс, найденный здесь, чтобы попытаться выполнить следующее:

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

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

Вот функции:

//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);
    }
4b9b3361

Ответ 1

Попробуйте этот класс PHP5 для шифрования с помощью mcrypt. В этом случае он использует шифрование AES. Вы захотите изменить ключ для каждого сайта, на котором вы его используете. Если вы его не используете, по крайней мере, это может привести вас к написанию вашей собственной версии.

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

Использование:

$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

Примечания:

  • Этот класс небезопасен для использования с двоичными данными (которые могут заканчиваться байтами NUL)
  • Этот класс не предоставляет аутентифицированное шифрование.

Ответ 2

В то время как ответ Джонса хорош, использование кодировки base64 только для устранения проблемы с двоичной безопасностью - это избыток и сделает ваши зашифрованные файлы на 33% больше, чем оригиналы. Вот мой PHP-реализация формата файла AES Crypt, который прозрачно решает все перечисленные выше проблемы.

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

Он двоично-безопасный и включает аутентифицированное шифрование. Так как он использует формат файла aes crypt с открытым исходным кодом (.aes), он полностью совместим с другим программным обеспечением .aes.

https://www.aescrypt.com/

Интерфейс довольно прост, шифруете ли вы или дешифруете. Вы просто даете ему исходный файл и пароль.

Ответ 3

CakePHP имеет довольно неплохую реализацию Rijndael. Я не размещаю код прямо здесь, потому что не уверен в юридических последствиях.

Вот api docs для метода Security::rijndael().

Если вы кодируете файл, вам нужно base64_encode() перед вызовом этого метода с encryptbase64_decode() после вызова этого метода с помощью <decrypt'

Ответ 4

Вы не должны использовать Mcrypt для шифрования/дешифрования данных. Как показано в вашем вопросе, и в принятом ответе данные не аутентифицируются, что означает, что он станет жертвой выбранных атак с зашифрованным текстом.

Кроме того, были предприняты большие усилия, чтобы разработчики правильно собрали криптографические примитивы. Таким образом, вместо Mcrypt вы должны использовать libsodium для своих проектов PHP. libsodium - это вилка NaCl. NaCl/libsodium написан для удаления множества криптографических ловушек, к которым приходят разработчики, таких как синхронизация с проверкой MAC-меток.

Mcrypt устарела в PHP 7.1, а libsodim - это предпочтительный способ обработки криптографии в PHP.

Использование libsodium в вашем проекте PHP просто и безопасно. Скотт Арчишевский написал обширную книгу об использовании libsodium с PHP в https://paragonie.com/book/pecl-libsodium. Это стоит прочитать для тех, кто делает криптографию PHP.