using System; using System.Security.Cryptography; using System.Text; using System.Text.Json; namespace CPT { public static class SecurityManager { // O "Salt" (Entropia) adiciona uma camada extra de segurança. // Mude esses valores para o seu projeto, mas guarde-os! // Se mudar o salt, não conseguirá descriptografar o que foi salvo antes. private static readonly byte[] OptionalEntropy = { 10, 22, 31, 45, 59 }; /// /// Criptografa uma string usando DPAPI e retorna em Base64. /// public static string Encrypt(string plainText) { if (string.IsNullOrEmpty(plainText)) return null; try { // Converte a string em bytes byte[] dataToEncrypt = Encoding.UTF8.GetBytes(plainText); // Criptografa os bytes vinculando-os à máquina local byte[] encryptedData = ProtectedData.Protect( dataToEncrypt, OptionalEntropy, DataProtectionScope.LocalMachine); // Retorna como string Base64 para facilitar o salvamento em arquivos (XML, JSON, Config) return Convert.ToBase64String(encryptedData); } catch (Exception ex) { // Em um sistema real, logue o erro em um arquivo de log throw new Exception("Falha ao criptografar os dados: " + ex.Message); } } /// /// Descriptografa uma string Base64 vinda do DPAPI. /// public static string Decrypt(string encryptedBase64) { if (string.IsNullOrEmpty(encryptedBase64)) return null; try { // Converte a string Base64 de volta para bytes byte[] dataToDecrypt = Convert.FromBase64String(encryptedBase64); // Descriptografa os bytes byte[] decryptedData = ProtectedData.Unprotect( dataToDecrypt, OptionalEntropy, DataProtectionScope.LocalMachine); // Retorna a string original return Encoding.UTF8.GetString(decryptedData); } catch (CryptographicException) { throw new Exception("A descriptografia falhou. O dado pode ter sido corrompido ou movido de máquina."); } catch (Exception ex) { throw new Exception("Erro genérico na descriptografia: " + ex.Message); } } // Classe que representa o que será salvo no arquivo public class AppConfig { public string EncryptedConnectionString { get; set; } } public static class ConfigProvider { // Caminho: C:\Users\Usuario\AppData\Local\NomeDoSeuApp\config.json private static readonly string FolderPath = Path.Combine( Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "LevelOS"); private static readonly string FilePath = Path.Combine(FolderPath, "config.json"); /// /// Salva a string de conexão criptografada no disco. /// public static void SalvarConexao(string connectionStringPura) { try { // 1. Criptografa a string usando nossa classe SecurityManager string encrypted = SecurityManager.Encrypt(connectionStringPura); // 2. Cria o objeto de configuração var config = new AppConfig { EncryptedConnectionString = encrypted }; // 3. Garante que a pasta existe if (!Directory.Exists(FolderPath)) Directory.CreateDirectory(FolderPath); // 4. Serializa para JSON string json = JsonSerializer.Serialize(config, new JsonSerializerOptions { WriteIndented = true }); // 5. Grava no arquivo File.WriteAllText(FilePath, json); } catch (Exception ex) { throw new Exception("Erro ao salvar arquivo de configuração: " + ex.Message); } } /// /// Lê do disco e retorna a string de conexão já descriptografada. /// public static string CarregarConexao() { try { if (!File.Exists(FilePath)) return null; // 1. Lê o JSON do arquivo string json = File.ReadAllText(FilePath); // 2. Deserializa var config = JsonSerializer.Deserialize(json); // 3. Descriptografa e retorna return SecurityManager.Decrypt(config.EncryptedConnectionString); } catch (Exception ex) { throw new Exception("Erro ao carregar configuração: " + ex.Message); } } } } }