using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace APIJSON.Data; public class SimpleStringCipher { public static SimpleStringCipher Instance { get; } /// /// This constant string is used as a "salt" value for the PasswordDeriveBytes function calls. /// This size of the IV (in bytes) must = (keysize / 8). Default keysize is 256, so the IV must be /// 32 bytes long. Using a 16 character string here gives us 32 bytes when converted to a byte array. /// public byte[] InitVectorBytes; /// /// Default password to encrypt/decrypt texts. /// It's recommented to set to another value for security. /// Default value: "gsKnGZ041HLL4IM8" /// public static string DefaultPassPhrase { get; set; } /// /// Default value: Encoding.ASCII.GetBytes("jkE49230Tf093b42") /// public static byte[] DefaultInitVectorBytes { get; set; } /// /// Default value: Encoding.ASCII.GetBytes("hgt!16kl") /// public static byte[] DefaultSalt { get; set; } /// /// This constant is used to determine the keysize of the encryption algorithm. /// public const int Keysize = 256; static SimpleStringCipher() { DefaultPassPhrase = "gsKnGZ041HLL4IM9"; DefaultInitVectorBytes = Encoding.ASCII.GetBytes("jkE49230Tf093b42"); DefaultSalt = Encoding.ASCII.GetBytes("hgt!11kl"); Instance = new SimpleStringCipher(); } public SimpleStringCipher() { InitVectorBytes = DefaultInitVectorBytes; } public string Encrypt(string plainText, string passPhrase = null, byte[] salt = null) { if (plainText == null) { return null; } if (passPhrase == null) { passPhrase = DefaultPassPhrase; } if (salt == null) { salt = DefaultSalt; } var plainTextBytes = Encoding.UTF8.GetBytes(plainText); using (var password = new Rfc2898DeriveBytes(passPhrase, salt)) { var keyBytes = password.GetBytes(Keysize / 8); using (var symmetricKey = Aes.Create()) { symmetricKey.Mode = CipherMode.CBC; using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, InitVectorBytes)) { using (var memoryStream = new MemoryStream()) { using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); var cipherTextBytes = memoryStream.ToArray(); return Convert.ToBase64String(cipherTextBytes); } } } } } } public string Decrypt(string cipherText, string passPhrase = null, byte[] salt = null) { if (string.IsNullOrEmpty(cipherText)) { return null; } if (passPhrase == null) { passPhrase = DefaultPassPhrase; } if (salt == null) { salt = DefaultSalt; } var cipherTextBytes = Convert.FromBase64String(cipherText); using (var password = new Rfc2898DeriveBytes(passPhrase, salt)) { var keyBytes = password.GetBytes(Keysize / 8); using (var symmetricKey = Aes.Create()) { symmetricKey.Mode = CipherMode.CBC; using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, InitVectorBytes)) { using (var memoryStream = new MemoryStream(cipherTextBytes)) { using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) { var plainTextBytes = new byte[cipherTextBytes.Length]; var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount); } } } } } } }