From cb387622154f56d63d901887b8f60f7cb70c1367 Mon Sep 17 00:00:00 2001 From: Kato Twofold Date: Sun, 28 Feb 2021 14:10:12 +0200 Subject: [PATCH] + File Decryption --- .gitignore | 3 ++- example-file.php | 26 +++++++++++++--------- lib.php | 58 +++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 71 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index d4e1a4e..a52da83 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ test_input_file.txt config.inc.php example.enc.php -example.dec.php \ No newline at end of file +example.dec.php +testdir \ No newline at end of file diff --git a/example-file.php b/example-file.php index 00ed250..b4a17f3 100644 --- a/example-file.php +++ b/example-file.php @@ -9,21 +9,28 @@ require("./lib.php"); * as low as possible. */ -define("INPUT_FILE", "./test_input_file.txt"); -define("OUTPUT_FILE", "./example.enc.php"); -define("DEC_OUTPUT_FILE", "./example.dec.php"); +define("INPUT_FILE", "./lib.php"); +define("OUTPUT_FILE", "./testdir/" . "./example.enc.php"); +define("DEC_OUTPUT_FILE", "./testdir/" . "./example.dec.php"); + +// Make sure the testing folder exists +if ( !file_exists("./testdir") ) { + mkdir("./testdir", 0777, true); +} // Initialize the class $lib = new kpcrypt(); +// $lib->setEncryptionBlocks(128); // This will take ~10 times more time, but will use half as much memory. +// Really the best value is the default one. + $enc_start = round(microtime(true) * 1000); // Encrypt the file $lib->encryptFile(INPUT_FILE, OUTPUT_FILE); $enc_end = round(microtime(true) * 1000) - $enc_start; - $dec_start = round(microtime(true) * 1000); // Decrypt the file as well @@ -36,15 +43,14 @@ $dec_end = round(microtime(true) * 1000) - $dec_start; */ echo "\n\n"; -echo "Input File Size: " . filesize(INPUT_FILE) / 1024 / 1024 . "Mb"; +echo "Input File Size: " . round(filesize(INPUT_FILE) / 1024 / 1024, 2) . "Mb"; echo "\n"; -echo "Output File Size: " . filesize(OUTPUT_FILE) / 1024 / 1024 . "Mb"; +echo "Output File Size: " . round(filesize(OUTPUT_FILE) / 1024 / 1024, 2) . "Mb"; echo "\n"; -echo "Peak Memory: " . memory_get_peak_usage() / 1024 / 1024 . "Mb"; // Check the memory in kb -echo "\n"; -echo "Encryption Time: $enc_end ms\n"; // 9700k = ~210ms +echo "Peak Memory: " . memory_get_peak_usage() / 1024 / 1024 . "Mb"; // Check the memory in Mb echo "\n"; +echo "Encryption Time: $enc_end ms\n"; // 9700k = ~210ms ( 4Mb = 100ms ) echo "Decryption Time: $dec_end ms\n"; -echo "\n\n"; +echo "\n"; $errors = $lib->getErrors(); echo "Errors: " . ( !empty($errors) ? "\n" . json_encode($errors, JSON_PRETTY_PRINT) : "No Errors!"); diff --git a/lib.php b/lib.php index 1a5d602..8db1e4b 100644 --- a/lib.php +++ b/lib.php @@ -15,14 +15,23 @@ class kpcrypt { private $key = null; /** - * Define the number of blocks that should be read from the source file for each chunk. - * For 'AES-128-CBC' each block consist of 16 bytes. - * So if we read 10,000 blocks we load 160kb into memory. You may adjust this value - * to read/write shorter or longer chunks. + * + * Define the number of blocks that should be read from the source file for each chunk. + * For 'AES-128-CBC' each block consist of 16 bytes. + * So if we read 10,000 blocks we load 160kb into memory. You may adjust this value + * to read/write shorter or longer chunks. + * + * The higher this size is, the faster the file will be + * processed but the more memory will in turn be also used + * */ private $blocks = 10000; - // A log of all of the errors, rather nice for debugging + /** + * A log of all of the errors, rather nice for debugging + * Please don't write to this, only read from it since + * it should only store errors about this class. + */ private $errorLog = []; // The encryption cipher to use @@ -148,6 +157,11 @@ class kpcrypt { // #endregion + /** + * File encryption should only be used on larger files ( 512kb+ ) + * Since the string encryption will work better on the smaller files, since it's all + * in the memory, this simlpy pipes the file through itself, for every 1Mb file it only uses ~0.1Mb of memory with the default block size + */ // #region File Encryption public function encryptFile(string $fileInput, string $fileOutput, bool $integrity_check = TRUE) { @@ -193,8 +207,42 @@ class kpcrypt { return 1; } + /** + * @param string $fileInput The path to the encrypted file we want to decrypt + * @param string $fileOutput The path to where to place the decrypted content + */ public function decryptFile(string $fileInput, string $fileOutput) { + + // Try and open the destionation + if ( $fout = fopen($fileOutput, 'w') ) { + // Try and open the input file + if ($fin = fopen($fileInput, 'rb') ) { + // Get the IV from the beginning of the file + $iv = fread($fin, openssl_cipher_iv_length($this->cipherMethod)); + + while (!feof($fin)) { + // we have to read one block more for decrypting than for encrypting + $ciphertext = fread($fin, 16 * ($this->blocks + 1)); + $plaintext = openssl_decrypt($ciphertext, $this->cipherMethod, $this->key, OPENSSL_RAW_DATA, $iv); + // Use the first 16 bytes of the ciphertext as the next initialization vector + $iv = substr($ciphertext, 0, 16); + fwrite($fout, $plaintext); + } + + // Close the input file + fclose($fin); + + } else { + $this->errorLog[] = "[" . __LINE__ . "]" . "Could not open file output path for writing."; + return false; + } + + // Close the output file + fclose($fout); + return 1; + } + } // #endregion