Defuse\Crypto\RuntimeTests::testEncryptDecrypt PHP Method

testEncryptDecrypt() private static method

High-level tests of Crypto operations.
private static testEncryptDecrypt ( )
    private static function testEncryptDecrypt()
    {
        $key = Key::createNewRandomKey();
        $data = "EnCrYpT EvErYThInG";
        // Make sure encrypting then decrypting doesn't change the message.
        $ciphertext = Crypto::encrypt($data, $key, true);
        try {
            $decrypted = Crypto::decrypt($ciphertext, $key, true);
        } catch (Ex\WrongKeyOrModifiedCiphertextException $ex) {
            // It's important to catch this and change it into a
            // Ex\EnvironmentIsBrokenException, otherwise a test failure could trick
            // the user into thinking it's just an invalid ciphertext!
            throw new Ex\EnvironmentIsBrokenException();
        }
        if ($decrypted !== $data) {
            throw new Ex\EnvironmentIsBrokenException();
        }
        // Modifying the ciphertext: Appending a string.
        try {
            Crypto::decrypt($ciphertext . 'a', $key, true);
            throw new Ex\EnvironmentIsBrokenException();
        } catch (Ex\WrongKeyOrModifiedCiphertextException $e) {
            /* expected */
        }
        // Modifying the ciphertext: Changing an HMAC byte.
        $indices_to_change = [0, Core::HEADER_VERSION_SIZE + 1, Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + 1, Core::HEADER_VERSION_SIZE + Core::SALT_BYTE_SIZE + Core::BLOCK_BYTE_SIZE + 1];
        foreach ($indices_to_change as $index) {
            try {
                $ciphertext[$index] = \chr((\ord($ciphertext[$index]) + 1) % 256);
                Crypto::decrypt($ciphertext, $key, true);
                throw new Ex\EnvironmentIsBrokenException();
            } catch (Ex\WrongKeyOrModifiedCiphertextException $e) {
                /* expected */
            }
        }
        // Decrypting with the wrong key.
        $key = Key::createNewRandomKey();
        $data = 'abcdef';
        $ciphertext = Crypto::encrypt($data, $key, true);
        $wrong_key = Key::createNewRandomKey();
        try {
            Crypto::decrypt($ciphertext, $wrong_key, true);
            throw new Ex\EnvironmentIsBrokenException();
        } catch (Ex\WrongKeyOrModifiedCiphertextException $e) {
            /* expected */
        }
        // Ciphertext too small.
        $key = Key::createNewRandomKey();
        $ciphertext = \str_repeat('A', Core::MINIMUM_CIPHERTEXT_SIZE - 1);
        try {
            Crypto::decrypt($ciphertext, $key, true);
            throw new Ex\EnvironmentIsBrokenException();
        } catch (Ex\WrongKeyOrModifiedCiphertextException $e) {
            /* expected */
        }
    }

Usage Example

Ejemplo n.º 1
0
 /**
  * Runs the runtime tests.
  *
  * @throws Ex\EnvironmentIsBrokenException
  */
 public static function runtimeTest()
 {
     // 0: Tests haven't been run yet.
     // 1: Tests have passed.
     // 2: Tests are running right now.
     // 3: Tests have failed.
     static $test_state = 0;
     if ($test_state === 1 || $test_state === 2) {
         return;
     }
     if ($test_state === 3) {
         /* If an intermittent problem caused a test to fail previously, we
          * want that to be indicated to the user with every call to this
          * library. This way, if the user first does something they really
          * don't care about, and just ignores all exceptions, they won't get
          * screwed when they then start to use the library for something
          * they do care about. */
         throw new Ex\EnvironmentIsBrokenException('Tests failed previously.');
     }
     try {
         $test_state = 2;
         Core::ensureFunctionExists('openssl_get_cipher_methods');
         if (\in_array(Core::CIPHER_METHOD, \openssl_get_cipher_methods()) === false) {
             throw new Ex\EnvironmentIsBrokenException('Cipher method not supported. This is normally caused by an outdated ' . 'version of OpenSSL (and/or OpenSSL compiled for FIPS compliance). ' . 'Please upgrade to a newer version of OpenSSL that supports ' . Core::CIPHER_METHOD . ' to use this library.');
         }
         RuntimeTests::AESTestVector();
         RuntimeTests::HMACTestVector();
         RuntimeTests::HKDFTestVector();
         RuntimeTests::testEncryptDecrypt();
         if (Core::ourStrlen(Key::createNewRandomKey()->getRawBytes()) != Core::KEY_BYTE_SIZE) {
             throw new Ex\EnvironmentIsBrokenException();
         }
         if (Core::ENCRYPTION_INFO_STRING == Core::AUTHENTICATION_INFO_STRING) {
             throw new Ex\EnvironmentIsBrokenException();
         }
     } catch (Ex\EnvironmentIsBrokenException $ex) {
         // Do this, otherwise it will stay in the "tests are running" state.
         $test_state = 3;
         throw $ex;
     }
     // Change this to '0' make the tests always re-run (for benchmarking).
     $test_state = 1;
 }