using System; using System.Collections.Generic; using System.Configuration; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using static System.Net.Mime.MediaTypeNames; namespace TrelloIntegration { /// /// Verschlüsselt und entschlüsselt Trello API-Key und Token mit AES. /// public static class TrelloConfig { /// /// Geheimer Schlüssel für Verschlüsselung (muss sicher gespeichert werden!) /// In Produktion besser aus Umgebungsvariablen oder sicherem Speicher lesen. /// private const string SecretKey = "DEIN_GEHEIMER_SCHLUESSEL_32_CHAR"; // 32 Zeichen für AES-256 /// /// Verschlüsselt einen Text und gibt Base64 zurück. /// public static string Encrypt(string plainText) { if (string.IsNullOrEmpty(plainText)) throw new ArgumentException("Text darf nicht leer sein", nameof(plainText)); var aes = Aes.Create(); aes.Key = Encoding.UTF8.GetBytes(SecretKey); aes.IV = new byte[16]; // IV für Demo; in Produktion zufällig generieren var encryptor = aes.CreateEncryptor(aes.Key, aes.IV); var plainBytes = Encoding.UTF8.GetBytes(plainText); var cipherBytes = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length); // IV + verschlüsselte Daten speichern (für Produktion mit zufälligem IV) var combined = new byte[aes.IV.Length + cipherBytes.Length]; Array.Copy(aes.IV, 0, combined, 0, aes.IV.Length); Array.Copy(cipherBytes, 0, combined, aes.IV.Length, cipherBytes.Length); return Convert.ToBase64String(combined); } /// /// Entschlüsselt einen Base64-Text. /// public static string Decrypt(string encryptedBase64) { if (string.IsNullOrEmpty(encryptedBase64)) throw new ArgumentException("Text darf nicht leer sein", nameof(encryptedBase64)); var combined = Convert.FromBase64String(encryptedBase64); var aes = Aes.Create(); aes.Key = Encoding.UTF8.GetBytes(SecretKey); // IV aus den ersten 16 Bytes extrahieren var iv = new byte[16]; Array.Copy(combined, 0, iv, 0, 16); aes.IV = iv; var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); var cipherBytes = new byte[combined.Length - 16]; Array.Copy(combined, 16, cipherBytes, 0, cipherBytes.Length); var plainBytes = decryptor.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length); return Encoding.UTF8.GetString(plainBytes); } /// /// Erstellt verschlüsselte Werte für App.config (einmalig ausführen). /// public static void CreateEncryptedConfigValues(string apiKey, string token) { var encryptedKey = Encrypt(apiKey); var encryptedToken = Encrypt(token); Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); config.AppSettings.Settings.Remove("TrelloApiKeyEncrypted"); config.AppSettings.Settings.Add("TrelloApiKeyEncrypted", encryptedKey); config.AppSettings.Settings.Remove("TrelloTokenEncrypted"); config.AppSettings.Settings.Add("TrelloTokenEncrypted", encryptedToken); config.Save(); Console.WriteLine("=== FÜR APP.CONFIG ==="); Console.WriteLine($""); Console.WriteLine($""); Console.WriteLine("======================"); } /// /// Gibt den API-Key aus App.config (entschlüsselt). /// public static string GetApiKey() { try { var encrypted = System.Configuration.ConfigurationManager .AppSettings["TrelloApiKeyEncrypted"]; return string.IsNullOrEmpty(encrypted) ? null : Decrypt(encrypted); } catch { return null; } } /// /// Gibt den Token aus App.config (entschlüsselt). /// public static string GetToken() { try { var encrypted = System.Configuration.ConfigurationManager .AppSettings["TrelloTokenEncrypted"]; return string.IsNullOrEmpty(encrypted) ? null : Decrypt(encrypted); } catch { return null; } } /// /// Prüft, ob verschlüsselte Credentials in App.config vorhanden sind. /// public static bool HasCredentials() { var key = System.Configuration.ConfigurationManager.AppSettings["TrelloApiKeyEncrypted"]; var token = System.Configuration.ConfigurationManager.AppSettings["TrelloTokenEncrypted"]; return !string.IsNullOrEmpty(key) && !string.IsNullOrEmpty(token); } } }