using System.Security.Cryptography; using System.Text; public class CryptoHelper { private RSA rsa; private string _publicKeyRsa; public CryptoHelper(UserProperties userProperties) { string publicKeyPath = Environment.CurrentDirectory + userProperties.Rsa.PublicKeyFile; string privateKeyPath = Environment.CurrentDirectory + userProperties.Rsa.PrivateKeyFile; Console.WriteLine("Loading public key from: {0}", publicKeyPath); Console.WriteLine("Loading private key from: {0}", privateKeyPath); rsa = RSA.Create(); rsa.ImportFromPem(File.ReadAllText(publicKeyPath)); rsa.ImportFromPem(File.ReadAllText(privateKeyPath)); _publicKeyRsa = Convert.ToBase64String(rsa.ExportSubjectPublicKeyInfo()); } public string GetPublicKeyRsa() => _publicKeyRsa; public byte[] DecryptEphemeralKey(string encryptedEphemeralKey) { return rsa.Decrypt(Convert.FromBase64String(encryptedEphemeralKey), RSAEncryptionPadding.OaepSHA512); } public async Task DecryptTextAsync(byte[] decryptedEphemeralKey, string encryptedText) { var decryptedBytes = await DecryptContentAsync(decryptedEphemeralKey, encryptedText); return Encoding.UTF8.GetString(decryptedBytes); } public async Task DecryptPhotoAsync(byte[] decryptedEphemeralKey, string encryptedPhoto) { var decryptedBytes = await DecryptContentAsync(decryptedEphemeralKey, encryptedPhoto); return Convert.ToBase64String(decryptedBytes); } public string EncryptText(byte[] decryptedEphemeralKey, string textValue) { return EncryptContent(decryptedEphemeralKey, Encoding.UTF8.GetBytes(textValue)); } public string EncryptPhoto(byte[] decryptedEphemeralKey, byte[] photoBytes) { return EncryptContent(decryptedEphemeralKey, photoBytes); } private async Task DecryptContentAsync(byte[] decryptedEphemeralKey, string encryptedData) { byte[] encryptedDataByteArray = Convert.FromBase64String(encryptedData); using MemoryStream memoryStream = new(encryptedDataByteArray); using Aes aes = Aes.Create(); aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.PKCS7; byte[] iv = new byte[aes.IV.Length]; int numBytesToRead = aes.IV.Length; int numBytesRead = 0; while (numBytesToRead > 0) { int n = memoryStream.Read(iv, numBytesRead, numBytesToRead); if (n == 0) { break; } numBytesRead += n; numBytesToRead -= n; } byte[] key = decryptedEphemeralKey; await using CryptoStream cryptoStream = new(memoryStream, aes.CreateDecryptor(key, iv), CryptoStreamMode.Read); using MemoryStream ms = new(); await cryptoStream.CopyToAsync(ms); var bytes = ms.ToArray(); return bytes; } private string EncryptContent(byte[] decryptedEphemeralKey, byte[] content) { byte[] encrypted; byte[] iv; using (var aesAlg = Aes.Create()) { aesAlg.Key = decryptedEphemeralKey; aesAlg.GenerateIV(); iv = aesAlg.IV; aesAlg.Mode = CipherMode.CBC; aesAlg.Padding = PaddingMode.PKCS7; // Create an encryptor to perform the stream transform. var encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for encryption. using (MemoryStream msEncrypt = new()) { using (CryptoStream csEncrypt = new(msEncrypt, encryptor, CryptoStreamMode.Write)) { //Write all data to the stream. csEncrypt.Write(content, 0, content.Length); } encrypted = msEncrypt.ToArray(); } } var combinedIvCt = new byte[iv.Length + encrypted.Length]; Array.Copy(iv, 0, combinedIvCt, 0, iv.Length); Array.Copy(encrypted, 0, combinedIvCt, iv.Length, encrypted.Length); var encryptedData = Convert.ToBase64String(combinedIvCt); return encryptedData; } }