Exemplo n.º 1
0
 /**
  * Decrypts a ciphertext (legacy -- before version tagging)
  *
  * $ciphertext is the ciphertext to decrypt.
  * $key is the key that the ciphertext was encrypted with.
  * You MUST catch exceptions thrown by this function. Read the docs.
  *
  * @param string $ciphertext
  * @param string $key
  * @return string
  * @throws Ex\CannotPerformOperationException
  * @throws Ex\CryptoTestFailedException
  * @throws Ex\InvalidCiphertextException
  */
 public static function legacyDecrypt($ciphertext, $key)
 {
     RuntimeTests::runtimeTest();
     $config = self::getVersionConfigFromHeader(Core::LEGACY_VERSION, Core::LEGACY_VERSION);
     // Extract the HMAC from the front of the ciphertext.
     if (Core::ourStrlen($ciphertext) <= $config->macByteSize()) {
         throw new Ex\InvalidCiphertextException("Ciphertext is too short.");
     }
     $hmac = Core::ourSubstr($ciphertext, 0, $config->macByteSize());
     if ($hmac === false) {
         throw new Ex\CannotPerformOperationException();
     }
     $ciphertext = Core::ourSubstr($ciphertext, $config->macByteSize());
     if ($ciphertext === false) {
         throw new Ex\CannotPerformOperationException();
     }
     // Regenerate the same authentication sub-key.
     $akey = Core::HKDF($config->hashFunctionName(), $key, $config->keyByteSize(), $config->authenticationInfoString(), null, $config);
     if (self::verifyHMAC($hmac, $ciphertext, $akey, $config)) {
         // Regenerate the same encryption sub-key.
         $ekey = Core::HKDF($config->hashFunctionName(), $key, $config->keyByteSize(), $config->encryptionInfoString(), null, $config);
         // Extract the initialization vector from the ciphertext.
         Core::EnsureFunctionExists("openssl_cipher_iv_length");
         $ivsize = \openssl_cipher_iv_length($config->cipherMethod());
         if ($ivsize === false || $ivsize <= 0) {
             throw new Ex\CannotPerformOperationException("Could not get the IV length from OpenSSL");
         }
         if (Core::ourStrlen($ciphertext) <= $ivsize) {
             throw new Ex\InvalidCiphertextException("Ciphertext is too short.");
         }
         $iv = Core::ourSubstr($ciphertext, 0, $ivsize);
         if ($iv === false) {
             throw new Ex\CannotPerformOperationException();
         }
         $ciphertext = Core::ourSubstr($ciphertext, $ivsize);
         if ($ciphertext === false) {
             throw new Ex\CannotPerformOperationException();
         }
         $plaintext = self::plainDecrypt($ciphertext, $ekey, $iv, $config);
         return $plaintext;
     } else {
         /*
          * We throw an exception instead of returning false because we want
          * a script that doesn't handle this condition to CRASH, instead
          * of thinking the ciphertext decrypted to the value false.
          */
         throw new Ex\InvalidCiphertextException("Integrity check failed.");
     }
 }