key = $this->key ?? config('mail_profiles.key'); if (empty($this->key)) { // Fall back to app key for now $this->key = config('app.key'); } } public function encrypt(string $plain): string { // For simplicity use Crypt facade (already uses APP_KEY) unless a dedicated key is set. if ($this->usingAppKey()) { return Crypt::encryptString($plain); } return $this->encryptWithCustomKey($plain); } public function decrypt(string $cipher): string { if ($this->usingAppKey()) { return Crypt::decryptString($cipher); } return $this->decryptWithCustomKey($cipher); } protected function usingAppKey(): bool { return $this->key === config('app.key'); } protected function encryptWithCustomKey(string $plain): string { $iv = random_bytes(openssl_cipher_iv_length('AES-256-CBC')); $cipher = openssl_encrypt($plain, 'AES-256-CBC', $this->normalizedKey(), 0, $iv); return base64_encode($iv.'::'.$cipher); } protected function decryptWithCustomKey(string $payload): string { $decoded = base64_decode($payload, true); if ($decoded === false || ! str_contains($decoded, '::')) { throw new DecryptException('Invalid encrypted payload'); } [$iv, $cipher] = explode('::', $decoded, 2); $plain = openssl_decrypt($cipher, 'AES-256-CBC', $this->normalizedKey(), 0, $iv); if ($plain === false) { throw new DecryptException('Cannot decrypt payload'); } return $plain; } protected function normalizedKey(): string { $raw = base64_decode($this->key, true); return $raw !== false ? $raw : $this->key; // support base64 or plain } }