key = $secrets['encryption_key'] ?? ''; // Ensure key is hexadecimal and convert to binary (32 bytes) if (strlen($this->key) === 64) { $this->key = hex2bin($this->key); } if (strlen($this->key) !== 32) { throw new Exception("Security Error: Invalid ENCRYPTION_KEY length. Must be 32 bytes."); } } public function encrypt(string $plaintext): string { $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(self::METHOD)); $ciphertext = openssl_encrypt($plaintext, self::METHOD, $this->key, 0, $iv, $tag); if ($ciphertext === false) { throw new Exception("Encryption failed."); } return base64_encode($iv) . ':' . base64_encode($ciphertext) . ':' . base64_encode($tag); } public function decrypt(string $encryptedData): string { $parts = explode(':', $encryptedData); if (count($parts) !== 3) { throw new Exception("Invalid encrypted data format."); } [$ivBase64, $ciphertextBase64, $tagBase64] = $parts; $iv = base64_decode($ivBase64); $ciphertext = base64_decode($ciphertextBase64); $tag = base64_decode($tagBase64); $plaintext = openssl_decrypt($ciphertext, self::METHOD, $this->key, 0, $iv, $tag); if ($plaintext === false) { throw new Exception("Decryption failed."); } return $plaintext; } }