Пытаясь написать пару функций, которые будут шифровать или дешифровать файл, и я использую класс, найденный здесь, чтобы попытаться выполнить следующее:
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); }
Попробуйте этот класс 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
Заметки:
Хотя ответ Джонса хорош, использование кодировки base64 только для исправления проблемы с двоичной безопасностью является излишним и сделает ваши зашифрованные файлы на 33% больше, чем оригиналы. Вот моя PHP-реализация формата файла AES Crypt, который прозрачно решает все перечисленные выше проблемы.
https://github.com/philios33/PHP-AES-File-Encryption
Он является двоичным и включает аутентифицированное шифрование. Так как он использует формат файла aes crypt с открытым исходным кодом (.aes), он полностью совместим с другим программным обеспечением .aes.
Интерфейс довольно прост, шифруете ли вы или дешифруете. Вы просто даете ему исходный файл и пароль.
CakePHP имеет довольно хорошую реализацию rijndael. Я не размещаю код прямо здесь, потому что не уверен в юридических последствиях.
Ниже приведены api docs для метода Security::rijndael()
.
Если вы кодируете файл, вам нужно будет использовать base64_encode()
перед вызовом этого метода с помощью « base64_decode()
и base64_decode()
после вызова этого метода с помощью « decrypt
»
Вы не должны использовать 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.