using System; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; namespace SWP.Core.MultiKeyEncryption { public class SecureConnectionString { const string _masterKey = "5AFD74B1C26E87FE6656099E850DC67A"; public class EncryptedData { public string EncryptedConnectionString { get; set; } public Dictionary UserMasterKeys { get; set; } = new(); } public EncryptedData EncryptConnectionString(string connectionString) { var encryptedConnString = EncryptWithKey(connectionString, _masterKey); var userKeys = new Dictionary(); return new EncryptedData { EncryptedConnectionString = encryptedConnString, UserMasterKeys = userKeys }; } public string AddNewUser(string username, string password) { var userKey = DeriveKeyFromPassword(password); var encryptedMasterKey = EncryptWithKey(_masterKey, userKey); return encryptedMasterKey; } public string Decrypt(string encryptedConnString, string encryptedMasterKey, string password) { var userKey = DeriveKeyFromPassword(password); var masterKey = DecryptWithKey(encryptedMasterKey, userKey); return DecryptWithKey(encryptedConnString, masterKey); } private string DeriveKeyFromPassword(string password) { using var deriveBytes = new Rfc2898DeriveBytes( password, new byte[16], // Fast salt for simpelhed - i produktion bør dette være unikt per bruger 10000, HashAlgorithmName.SHA256); return Convert.ToBase64String(deriveBytes.GetBytes(32)); } private string EncryptWithKey(string value, string key) { using var aes = Aes.Create(); var keyBytes = Convert.FromBase64String(key); aes.Key = keyBytes; aes.GenerateIV(); using var encryptor = aes.CreateEncryptor(); var valueBytes = Encoding.UTF8.GetBytes(value); var encrypted = encryptor.TransformFinalBlock(valueBytes, 0, valueBytes.Length); var result = new byte[aes.IV.Length + encrypted.Length]; Array.Copy(aes.IV, 0, result, 0, aes.IV.Length); Array.Copy(encrypted, 0, result, aes.IV.Length, encrypted.Length); return Convert.ToBase64String(result); } private string DecryptWithKey(string encryptedValue, string key) { var encryptedBytes = Convert.FromBase64String(encryptedValue); using var aes = Aes.Create(); var keyBytes = Convert.FromBase64String(key); aes.Key = keyBytes; var iv = new byte[16]; Array.Copy(encryptedBytes, 0, iv, 0, iv.Length); aes.IV = iv; using var decryptor = aes.CreateDecryptor(); var decrypted = decryptor.TransformFinalBlock( encryptedBytes, iv.Length, encryptedBytes.Length - iv.Length); return Encoding.UTF8.GetString(decrypted); } } }