using System.Security.Cryptography; using System.Text; namespace RelayServer.Services.Chat; public sealed class ChannelCryptoService { public string GenerateKey() { return Convert.ToBase64String(RandomNumberGenerator.GetBytes(32)); } public (string cipherText, string nonce, string tag) Encrypt(string plainText, string keyBase64) { var key = Convert.FromBase64String(keyBase64); var nonce = RandomNumberGenerator.GetBytes(12); var plainBytes = Encoding.UTF8.GetBytes(plainText); var cipherBytes = new byte[plainBytes.Length]; var tag = new byte[16]; using var aes = new AesGcm(key, 16); aes.Encrypt(nonce, plainBytes, cipherBytes, tag); return ( Convert.ToBase64String(cipherBytes), Convert.ToBase64String(nonce), Convert.ToBase64String(tag) ); } public string Decrypt(string cipherTextBase64, string nonceBase64, string tagBase64, string keyBase64) { var key = Convert.FromBase64String(keyBase64); var nonce = Convert.FromBase64String(nonceBase64); var tag = Convert.FromBase64String(tagBase64); var cipherBytes = Convert.FromBase64String(cipherTextBase64); var plainBytes = new byte[cipherBytes.Length]; using var aes = new AesGcm(key, 16); aes.Decrypt(nonce, cipherBytes, tag, plainBytes); return Encoding.UTF8.GetString(plainBytes); } }