// Supress warnings due to .NET 3.5 compatibility
        // ReSharper disable SuspiciousTypeConversion.Global
        #pragma warning disable S1944 // Inappropriate casts should not be made
        private static DeriveResult DeriveBytes(string key)
        {
            var deriver = new Rfc2898DeriveBytes(key, SaltSize);
            var result  = new DeriveResult
            {
                Salt = deriver.Salt,
                Key  = deriver.GetBytes(32),
                InitializationVector = deriver.GetBytes(16)
            };

            (deriver as IDisposable)?.Dispose();
            return(result);
        }
        private static DeriveResult DeriveBytes(string key, byte[] saltBytes)
        {
            var deriver = new Rfc2898DeriveBytes(key, saltBytes);

            // Derive the previous IV from the Key and Salt
            var result = new DeriveResult
            {
                Key = deriver.GetBytes(32),
                InitializationVector = deriver.GetBytes(16)
            };

            (deriver as IDisposable)?.Dispose();
            return(result);
        }
 private static string DecryptStream(byte[] cipher, DeriveResult keys)
 {
     // Create a decrytor to perform the stream transform.
     // Create the streams used for decryption.
     // The default Cipher Mode is CBC and the Padding is PKCS7 which are both good
     using (var aesManaged = new AesManaged())
         using (var decryptor = aesManaged.CreateDecryptor(keys.Key, keys.InitializationVector))
             using (var memoryStream = new MemoryStream(cipher))
                 using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
                     using (var streamReader = new StreamReader(cryptoStream))
                     {
                         // Return the decrypted keys from the decrypting stream.
                         return(streamReader.ReadToEnd());
                     }
 }
        private static byte[] EncryptStream(string clearText, DeriveResult bytes)
        {
            // Create an encryptor to perform the stream transform.
            // Create the streams used for encryption.
            using (var aesManaged = new AesManaged())
                using (var encryptor = aesManaged.CreateEncryptor(bytes.Key, bytes.InitializationVector))
                    using (var memoryStream = new MemoryStream())
                    {
                        using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
                            using (var streamWriter = new StreamWriter(cryptoStream))
                            {
                                // Send the data through the StreamWriter, through the CryptoStream, to the underlying MemoryStream
                                streamWriter.Write(clearText);

                                // vv Have to dispose of the SW here in order to maintain the integrity of the memoryStream.
                            }

                        // Return the encrypted keys from the memory stream, in Base64 form so we can send it right to a database (if we want).
                        var cipherTextBytes = memoryStream.ToArray();
                        return(cipherTextBytes);
                    }
        }