key = $encryptionKey; $iv = substr($this->key, 0, 16); $this->decryptCipher = new Cipher(self::ENCRYPTION_SCHEME); $this->decryptCipher->decryptInit($this->key, $iv); $this->encryptCipher = new Cipher(self::ENCRYPTION_SCHEME); $this->encryptCipher->encryptInit($this->key, $iv); } /** * @throws DecryptionException */ public function decrypt(string $encrypted) : string{ if(strlen($encrypted) < 9){ throw new DecryptionException("Payload is too short"); } $decrypted = $this->decryptCipher->decryptUpdate($encrypted); $payload = substr($decrypted, 0, -8); if(($expected = $this->calculateChecksum($this->decryptCounter++, $payload)) !== ($actual = substr($decrypted, -8))){ throw new DecryptionException("Encrypted payload has invalid checksum (expected " . bin2hex($expected) . ", got " . bin2hex($actual) . ")"); } return $payload; } public function encrypt(string $payload) : string{ return $this->encryptCipher->encryptUpdate($payload . $this->calculateChecksum($this->encryptCounter++, $payload)); } private function calculateChecksum(int $counter, string $payload) : string{ $hash = openssl_digest(Binary::writeLLong($counter) . $payload . $this->key, self::CHECKSUM_ALGO, true); if($hash === false){ throw new \RuntimeException("Encryption error: " . openssl_error_string()); } return substr($hash, 0, 8); } }