validateKey($this->encryptionKey)) { throw new RuntimeException('Encryption key must be at least ' . self::MIN_KEY_LENGTH . ' characters'); } } public function encrypt(string $data): string { // Generate a random salt $salt = $this->randomGenerator->bytes(8); $saltHex = bin2hex($salt); // Create expanded key from base key + salt $expandedKey = hash('sha256', $this->encryptionKey . $saltHex, true); // Simple XOR encryption (NOT secure, only for fallback!) $encrypted = $this->xorEncrypt($data, $expandedKey); // Combine salt + encrypted data $payload = base64_encode($salt . $encrypted); return self::PREFIX . $payload . self::SUFFIX; } public function decrypt(string $encryptedData): string { if (! $this->isEncrypted($encryptedData)) { throw new RuntimeException('Data does not appear to be encrypted with this method'); } // Remove prefix and suffix $payload = substr( $encryptedData, strlen(self::PREFIX), -strlen(self::SUFFIX) ); $data = base64_decode($payload); if ($data === false) { throw new RuntimeException('Invalid base64 encoding in encrypted data'); } if (strlen($data) < 8) { throw new RuntimeException('Encrypted data is too short to contain valid salt'); } // Extract salt and encrypted data $salt = substr($data, 0, 8); $encrypted = substr($data, 8); $saltHex = bin2hex($salt); // Recreate expanded key $expandedKey = hash('sha256', $this->encryptionKey . $saltHex, true); // Decrypt using XOR return $this->xorDecrypt($encrypted, $expandedKey); } public function isEncrypted(string $data): bool { return str_starts_with($data, self::PREFIX) && str_ends_with($data, self::SUFFIX); } public function getMethod(): string { return self::METHOD; } public function validateKey(string $key): bool { return strlen($key) >= self::MIN_KEY_LENGTH; } /** * Simple XOR encryption (NOT cryptographically secure!) */ private function xorEncrypt(string $data, string $key): string { $result = ''; $keyLen = strlen($key); $dataLen = strlen($data); for ($i = 0; $i < $dataLen; $i++) { $result .= $data[$i] ^ $key[$i % $keyLen]; } return $result; } /** * Simple XOR decryption (same as encryption for XOR) */ private function xorDecrypt(string $encrypted, string $key): string { return $this->xorEncrypt($encrypted, $key); // XOR is symmetric } /** * Generate a new encryption key suitable for basic encryption */ public function generateKey(): string { return base64_encode($this->randomGenerator->bytes(self::MIN_KEY_LENGTH)); } /** * Get encryption metadata for debugging/logging */ public function getMetadata(): array { return [ 'method' => self::METHOD, 'key_length' => self::MIN_KEY_LENGTH, 'prefix' => self::PREFIX, 'suffix' => self::SUFFIX, 'warning' => 'NOT CRYPTOGRAPHICALLY SECURE - DEVELOPMENT ONLY', ]; } }