/// <summary> /// Decrypts a byte array with a password /// </summary> /// <param name="data">Data to decrypt</param> /// <param name="password">Password to use</param> /// <param name="paddingMode">Padding mode to use</param> /// <returns>Decrypted byte array</returns> /// <exception cref="System.ArgumentNullException"> /// data /// or /// password /// </exception> /// <exception cref="ArgumentNullException"></exception> public static byte[] DecryptData(byte[] data, string password, PaddingMode paddingMode) { if (data == null || data.Length == 0) throw new ArgumentNullException("data"); if (password == null) throw new ArgumentNullException("password"); var pdb = new PasswordDeriveBytes(password, Encoding.UTF8.GetBytes("Salt")); var rm = new RijndaelManaged { Padding = paddingMode }; ICryptoTransform decryptor = rm.CreateDecryptor(pdb.GetBytes(16), pdb.GetBytes(16)); pdb.Dispose(); using (var msDecrypt = new MemoryStream(data)) using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { // Decrypted bytes will always be less then encrypted bytes, so length of encrypted data will be big enough for buffer. byte[] fromEncrypt = new byte[data.Length]; // Read as many bytes as possible. int read = csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length); if (read < fromEncrypt.Length) { // Return a byte array of proper size. byte[] clearBytes = new byte[read]; Buffer.BlockCopy(fromEncrypt, 0, clearBytes, 0, read); return clearBytes; } return fromEncrypt; } }
private SymmetricAlgorithm CreateSymmetricAlgorithm(string password) { var pdb = new PasswordDeriveBytes(password, new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }); try { var AESE = new AesManaged(); AESE.Key = pdb.GetBytes(AESE.KeySize / 8); AESE.IV = pdb.GetBytes(AESE.BlockSize / 8); return AESE; } finally { #if !NET35 if (pdb != null) pdb.Dispose(); #endif } }
/// <summary> /// Encrypts a byte array with a password /// </summary> /// <param name="data">Data to encrypt</param> /// <param name="password">Password to use</param> /// <param name="paddingMode">Padding mode to use</param> /// <returns>Encrypted byte array</returns> /// <exception cref="System.ArgumentNullException"> /// data /// or /// password /// </exception> /// <exception cref="ArgumentNullException"></exception> public static byte[] EncryptData(byte[] data, string password, PaddingMode paddingMode) { if (data == null || data.Length == 0) throw new ArgumentNullException("data"); if (password == null) throw new ArgumentNullException("password"); var pdb = new PasswordDeriveBytes(password, Encoding.UTF8.GetBytes("Salt")); var rm = new RijndaelManaged { Padding = paddingMode }; ICryptoTransform encryptor = rm.CreateEncryptor(pdb.GetBytes(16), pdb.GetBytes(16)); pdb.Dispose(); using (var msEncrypt = new MemoryStream()) using (var encStream = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write)) { encStream.Write(data, 0, data.Length); encStream.FlushFinalBlock(); return msEncrypt.ToArray(); } }
/// <summary> /// Decrypts specified ciphertext using Rijndael symmetric key algorithm. /// </summary> /// <param name="cipherText"> /// Base64-formatted ciphertext value. /// </param> /// <param name="passPhrase"> /// Passphrase from which a pseudo-random password will be derived. The /// derived password will be used to generate the encryption key. /// Passphrase can be any string. In this example we assume that this /// passphrase is an ASCII string. /// </param> /// <param name="saltValue"> /// Salt value used along with passphrase to generate password. Salt can /// be any string. In this example we assume that salt is an ASCII string. /// </param> /// <returns> /// Decrypted string value. /// </returns> /// <remarks> /// Most of the logic in this function is similar to the Encrypt /// logic. In order for decryption to work, all parameters of this function /// - except cipherText value - must match the corresponding parameters of /// the Encrypt function which was called to generate the /// ciphertext. /// </remarks> public static string Decrypt (string cipherText, string passPhrase, string saltValue) { // Convert strings defining encryption key characteristics into byte // arrays. Let us assume that strings only contain ASCII codes. // If strings include Unicode characters, use Unicode, UTF7, or UTF8 // encoding. byte [] initVectorBytes = Encoding.ASCII.GetBytes ("@IBAg3D4e5E6g7H5"); byte [] saltValueBytes = Encoding.ASCII.GetBytes (saltValue); // Convert our ciphertext into a byte array. byte [] cipherTextBytes = Convert.FromBase64String (cipherText); // First, we must create a password, from which the key will be // derived. This password will be generated from the specified // passphrase and salt value. The password will be created using // the specified hash algorithm. Password creation can be done in // several iterations. PasswordDeriveBytes password = new PasswordDeriveBytes ( passPhrase, saltValueBytes, EncryptorType, EncryptIterations); // Use the password to generate pseudo-random bytes for the encryption // key. Specify the size of the key in bytes (instead of bits). byte [] keyBytes = password.GetBytes (KeySize / 8); password.Dispose (); // Create uninitialized Rijndael encryption object. RijndaelManaged symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC }; // It is reasonable to set encryption mode to Cipher Block Chaining // (CBC). Use default options for other symmetric key parameters. // Generate decryptor from the existing key bytes and initialization // vector. Key size will be defined based on the number of the key // bytes. ICryptoTransform decryptor = symmetricKey.CreateDecryptor (keyBytes, initVectorBytes); // Define memory stream which will be used to hold encrypted data. MemoryStream memoryStream = new MemoryStream (cipherTextBytes); // Define cryptographic stream (always use Read mode for encryption). CryptoStream cryptoStream = new CryptoStream (memoryStream, decryptor, CryptoStreamMode.Read); // Since at this point we don't know what the size of decrypted data // will be, allocate the buffer long enough to hold ciphertext; // plaintext is never longer than ciphertext. byte [] plainTextBytes = new byte [cipherTextBytes.Length]; // Start decrypting. int decryptedByteCount = 0; try { decryptedByteCount = cryptoStream.Read (plainTextBytes, 0, plainTextBytes.Length); } catch (Exception) { return ""; } // Close both streams. cryptoStream.Close (); // Convert decrypted data into a string. // Let us assume that the original plaintext string was UTF8-encoded. string plainText = Encoding.UTF8.GetString (plainTextBytes, 0, decryptedByteCount); // Return decrypted string. return plainText; }
/// <summary> /// Encrypts specified plaintext using Rijndael symmetric key algorithm /// and returns a base64-encoded result. /// </summary> /// <param name="plainText"> /// Plaintext value to be encrypted. /// </param> /// <param name="passPhrase"> /// Passphrase from which a pseudo-random password will be derived. The /// derived password will be used to generate the encryption key. /// Passphrase can be any string. In this example we assume that this /// passphrase is an ASCII string. /// </param> /// <param name="saltValue"> /// Salt value used along with passphrase to generate password. Salt can /// be any string. In this example we assume that salt is an ASCII string. /// </param> /// <returns> /// Encrypted value formatted as a base64-encoded string. /// </returns> public static string Encrypt (string plainText, string passPhrase, string saltValue) { // Convert strings into byte arrays. // Let us assume that strings only contain ASCII codes. // If strings include Unicode characters, use Unicode, UTF7, or UTF8 // encoding. byte [] initVectorBytes = Encoding.ASCII.GetBytes ("@IBAg3D4e5E6g7H5"); byte [] saltValueBytes = Encoding.ASCII.GetBytes (saltValue); // Convert our plaintext into a byte array. // Let us assume that plaintext contains UTF8-encoded characters. byte [] plainTextBytes = Encoding.UTF8.GetBytes (plainText); // First, we must create a password, from which the key will be derived. // This password will be generated from the specified passphrase and // salt value. The password will be created using the specified hash // algorithm. Password creation can be done in several iterations. PasswordDeriveBytes password = new PasswordDeriveBytes ( passPhrase, saltValueBytes, EncryptorType, EncryptIterations); // Use the password to generate pseudo-random bytes for the encryption // key. Specify the size of the key in bytes (instead of bits). byte [] keyBytes = password.GetBytes (KeySize / 8); password.Dispose (); // Create uninitialized Rijndael encryption object. RijndaelManaged symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC }; // It is reasonable to set encryption mode to Cipher Block Chaining // (CBC). Use default options for other symmetric key parameters. // Generate encryptor from the existing key bytes and initialization // vector. Key size will be defined based on the number of the key // bytes. ICryptoTransform encryptor = symmetricKey.CreateEncryptor (keyBytes, initVectorBytes); // Define memory stream which will be used to hold encrypted data. string cipherText = string.Empty; MemoryStream memoryStream = new MemoryStream (); CryptoStream cryptoStream = null; try { // Define cryptographic stream (always use Write mode for encryption). cryptoStream = new CryptoStream (memoryStream, encryptor, CryptoStreamMode.Write); // Start encrypting. cryptoStream.Write (plainTextBytes, 0, plainTextBytes.Length); // Finish encrypting. cryptoStream.FlushFinalBlock (); // Convert our encrypted data from a memory stream into a byte array. byte [] cipherTextBytes = memoryStream.ToArray (); // Close both streams. cryptoStream.Close (); // Convert encrypted data into a base64-encoded string. cipherText = Convert.ToBase64String (cipherTextBytes); } catch { if (cryptoStream != null) cryptoStream.Close (); } // Return encrypted string. return cipherText; }