using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace SNote.Server.Security; public static class SecurityHelper { // Encrypts plaintext using AES-256 with a randomized IV, prepending IV to the ciphertext. public static string Encrypt(string plaintext, string base64Key) { if (string.IsNullOrEmpty(plaintext)) return plaintext; try { var keyBytes = Convert.FromBase64String(base64Key); using var aes = Aes.Create(); aes.Key = keyBytes; aes.GenerateIV(); var iv = aes.IV; using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV); using var ms = new MemoryStream(); // Prepend IV ms.Write(iv, 0, iv.Length); using (var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write)) using (var sw = new StreamWriter(cs, Encoding.UTF8)) { sw.Write(plaintext); } return Convert.ToBase64String(ms.ToArray()); } catch (Exception ex) { Console.WriteLine($"Encryption error: {ex.Message}"); return plaintext; } } // Decrypts ciphertext (which has prepended IV) using AES-256. public static string Decrypt(string ciphertext, string base64Key) { if (string.IsNullOrEmpty(ciphertext)) return ciphertext; try { var fullCipher = Convert.FromBase64String(ciphertext); var keyBytes = Convert.FromBase64String(base64Key); using var aes = Aes.Create(); aes.Key = keyBytes; var iv = new byte[16]; var cipherTextBytes = new byte[fullCipher.Length - 16]; Buffer.BlockCopy(fullCipher, 0, iv, 0, 16); Buffer.BlockCopy(fullCipher, 16, cipherTextBytes, 0, cipherTextBytes.Length); aes.IV = iv; using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV); using var ms = new MemoryStream(cipherTextBytes); using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read); using var sr = new StreamReader(cs, Encoding.UTF8); return sr.ReadToEnd(); } catch (Exception ex) { Console.WriteLine($"Decryption error: {ex.Message}. Returning ciphertext as-is."); return ciphertext; } } // Server-to-server signing token or helper (optional, or we do JWTs) }