using System; using System.IO; using System.Security.Cryptography; using System.Text; namespace DataModel.Helpers { /// /// Helper methods for encryption / decryption /// public class EncryptionHelper { /// /// Default salt value /// private const string DEFAULT_SALT = ")kjdnl3k1jh234a9"; /// /// Default hashing algorithm to use /// private const string DEFAULT_HASH_ALGORITHM = "SHA1"; /// /// Default number of iterations to do /// private const int DEFAULT_PASSWORD_ITERATION = 2; /// /// Default initialization vector /// private const string DEFAULT_INITIAL_VECTOR = "X8pgVu239uOjdKH1"; /// /// Default encryption keysize /// private const int DEFAULT_KEYSIZE = 256; /// /// Encrypts a string /// /// Text to be encrypted /// Password to encrypt with /// Salt to encrypt with /// Can be either SHA1 or MD5 /// Number of iterations to do /// Needs to be 16 ASCII characters long /// Can be 128, 192, or 256 /// An encrypted string public static string Encrypt(string plainText, string password, string salt = DEFAULT_SALT, string hashAlgorithm = DEFAULT_HASH_ALGORITHM, int passwordIterations = DEFAULT_PASSWORD_ITERATION, string initialVector = DEFAULT_INITIAL_VECTOR, int keySize = DEFAULT_KEYSIZE) { if (string.IsNullOrEmpty(plainText)) { return ""; } byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt); byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText); PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations); byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); RijndaelManaged symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC }; byte[] cipherTextBytes = null; using (ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initialVectorBytes)) { using (MemoryStream memStream = new MemoryStream()) { using (CryptoStream cryptoStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write)) { cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length); cryptoStream.FlushFinalBlock(); cipherTextBytes = memStream.ToArray(); memStream.Close(); cryptoStream.Close(); } } } symmetricKey.Clear(); return Convert.ToBase64String(cipherTextBytes); } /// /// Decrypts a string /// /// Text to be decrypted /// Password to decrypt with /// Salt to decrypt with /// Can be either SHA1 or MD5 /// Number of iterations to do /// Needs to be 16 ASCII characters long /// Can be 128, 192, or 256 /// A decrypted string public static string Decrypt(string encrypted, string password, string salt = DEFAULT_SALT, string hashAlgorithm = DEFAULT_HASH_ALGORITHM, int passwordIterations = DEFAULT_PASSWORD_ITERATION, string initialVector = DEFAULT_INITIAL_VECTOR, int keySize = DEFAULT_KEYSIZE) { if (string.IsNullOrEmpty(encrypted)) { return ""; } byte[] initialVectorBytes = Encoding.ASCII.GetBytes(initialVector); byte[] saltValueBytes = Encoding.ASCII.GetBytes(salt); byte[] cipherTextBytes = Convert.FromBase64String(encrypted); PasswordDeriveBytes derivedPassword = new PasswordDeriveBytes(password, saltValueBytes, hashAlgorithm, passwordIterations); byte[] keyBytes = derivedPassword.GetBytes(keySize / 8); RijndaelManaged symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC }; byte[] plainTextBytes = new byte[cipherTextBytes.Length]; int byteCount = 0; using (ICryptoTransform decrypt = symmetricKey.CreateDecryptor(keyBytes, initialVectorBytes)) { using (MemoryStream memStream = new MemoryStream(cipherTextBytes)) { using (CryptoStream cryptoStream = new CryptoStream(memStream, decrypt, CryptoStreamMode.Read)) { byteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length); memStream.Close(); cryptoStream.Close(); } } } symmetricKey.Clear(); return Encoding.UTF8.GetString(plainTextBytes, 0, byteCount); } } }