/** * Decrypt ciphertext into plaintext. * * @param EncryptedData|string $ciphertext The data to be decrypted. * * @return string the decrypted plaintext * * @throws MessageTamperingException if the message has been tampered with. */ public function decrypt($ciphertext) { $data = $ciphertext instanceof EncryptedData ? $ciphertext : EncryptedData::fromText($ciphertext); if (!($data->getHash() === $this->hash && $data->getCipher() === $this->cipher)) { return static::with($this->key)->withHash($data->getHash(), $data->getHashBytes())->withCipher($data->getCipher(), $data->getKeyBytes(), $data->getIvBytes())->decrypt($ciphertext); } $auth_should_be = hash_hmac($this->hash, $data->getIv() . $data->getCiphertext(), $this->getDerivedAuthenticationKey(), true); if ($auth_should_be !== $data->getAuth()) { throw new MessageTamperingException('Could not decrypt this message. It has been tampered with or forged.'); } $plaintext = openssl_decrypt($data->getCiphertext(), $this->cipher, $this->getDerivedEncryptionKey(), OPENSSL_RAW_DATA, $data->getIv()); if (false === $plaintext) { throw new RuntimeException('Could not decrypt this message. openssl_decrypt failed'); } return $plaintext; }
/** * Create an instance of TamperableEncryptedData from an EncryptedData instance. * * @param EncryptedData $other * * @return TamperableEncryptedData */ public static function fromBase(EncryptedData $other) { return static::fromArray($other->toArray()); }