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);
}
}
}
}
}