/** * Tests the serialization and de-serialization of an EncryptedFile object */ public function testSerializiation() { // Test whether serialization doesn't return empty $serialized = serialize($this->file); $this->assertNotEmpty($serialized); // Test whether serialization returned the proper object $file = unserialize($serialized); $this->assertInstanceOf(EncryptedFile::class, $file); // Test whether the objects are the same $this->assertEquals($this->file->getIv(), $file->getIv()); $this->assertEquals($this->file->getChecksum(), $file->getChecksum()); $this->assertEquals($this->file->getPadding(), $file->getPadding()); $this->assertEquals($this->file->getFile(), $file->getFile()); // Test whether the file property is still an instance of SplFileInfo $this->assertInstanceOf(\SplFileInfo::class, $file->getFile()); }
/** * Decrypts a file in a stream, performing the callback on each successive decrypted block. * If the checksum is provided it checks it against the encrypted file for integrity. * * The callback can accept two arguments: * - $data - A chunk of decrypted data * - $stream - The resource stream that is decrypting * * @param EncryptedFile $encryptedFile * @param \Closure $callback * @throws DecryptException */ public function streamDecrypt(EncryptedFile $encryptedFile, \Closure $callback) { // Get the path to the encrypted file $source = $encryptedFile->getFile()->getRealPath(); // Get the decryption stream try { $stream = $this->createDecryptionStream($source, $this->getOptions($encryptedFile->getIv())); } catch (\Exception $e) { throw new DecryptException('Unable to create decryption stream', 0, $e); } // Run the callback while the file pointer isn't at the end while (!feof($stream)) { $data = fread($stream, self::CHUNK_BYTES); // Trim the padded bytes off of the data once EOF has been reached if (feof($stream)) { $data = substr($data, 0, -$encryptedFile->getPadding()); } $callback($data, $stream); } }
/** * Test decryption */ public function testDecrypt() { $encryptedFile = $this->fileCrypt->encrypt($this->test_file, $this->test_encrypted_file); $this->fileCrypt->decrypt($encryptedFile, $this->test_decrypted_file); // Test if the decrypted file exists $this->assertTrue(file_exists($this->test_decrypted_file)); // Test if the checksum equals the original file $this->assertEquals($encryptedFile->getChecksum(), sha1_file($this->test_decrypted_file)); // Test if the decrypted file contains the same content as the original $this->assertEquals(file_get_contents($this->test_file), file_get_contents($this->test_decrypted_file)); // Test decryption of encrypted file with incorrect wrong IV try { $invalidEncryptedFile = EncryptedFile::create('2394qsf3-f9', $encryptedFile->getChecksum(), $encryptedFile->getPadding(), $encryptedFile->getFile()->getRealPath()); $this->fileCrypt->decrypt($invalidEncryptedFile, $this->test_decrypted_file); $this->fail('No exception was thrown on decrypting with an incorrect IV'); } catch (\Exception $e) { $this->assertInstanceOf(DecryptException::class, $e); } // Test decryption of encrypted file with incorrect checksum // We perform this test by setting the expected exception $this->setExpectedException(DecryptException::class); $invalidEncryptedFile = EncryptedFile::create($encryptedFile->getIV(), bin2hex(openssl_random_pseudo_bytes(16)), $encryptedFile->getPadding() * 2, $encryptedFile->getFile()->getRealPath()); $this->fileCrypt->decrypt($invalidEncryptedFile, $this->test_decrypted_file); }