I've been trying to learn some more about System.Security.Cryptography in c# with online docs & samples. So far I have been able to encrypt/decrypt both text and files successfully; however, i got an exception thrown when i tried to decrypt with an incorrect key.
Blockquote System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.'
Encryption
private static byte[] EncryptData(SymmetricAlgorithms symmetricAlgorithm, byte[] inputBytes, byte[] key)
    {
        byte[] output;
        using (SymmetricAlgorithm algorithm = SymmetricAlgorithmFactory(symmetricAlgorithm))
        {
            byte[] encrypted;
            byte[] salt = new byte[PBKDF2_SaltBytes];
            int maxKeySize = GetLegalKeySizes(algorithm).Max();
            _rng.GetBytes(salt); //
            using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(key, salt, PBKDF2_Iterations))
            {
                algorithm.Key = pbkdf2.GetBytes(maxKeySize);
            }
            //algorithm.Padding = PaddingMode.PKCS7;
            using (ICryptoTransform cryptoTransform = algorithm.CreateEncryptor())
            {
                using (MemoryStream inputStream = new MemoryStream(inputBytes), transformedStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream(inputStream, cryptoTransform, CryptoStreamMode.Read))
                    {
                        cryptoStream.CopyTo(transformedStream);
                    }
                    encrypted = transformedStream.ToArray();
                }
            }
            output = new byte[salt.Length + algorithm.IV.Length + encrypted.Length];
            Buffer.BlockCopy(salt, 0, output, 0, salt.Length);
            Buffer.BlockCopy(algorithm.IV, 0, output, salt.Length, algorithm.IV.Length);
            Buffer.BlockCopy(encrypted, 0, output, salt.Length + algorithm.IV.Length, encrypted.Length);
        }
        return output;
    }
Decryption
private static byte[] DecryptData(SymmetricAlgorithms symmetricAlgorithm, byte[] inputBytes, byte[] key)
    {
        using (SymmetricAlgorithm algorithm = SymmetricAlgorithmFactory(symmetricAlgorithm))
        {
            byte[] salt = new byte[PBKDF2_SaltBytes];
            byte[] iv = new byte[algorithm.IV.Length];
            byte[] encryptedData = new byte[inputBytes.Length - salt.Length - iv.Length];
            int maxKeySize = GetLegalKeySizes(algorithm).Max();
            Buffer.BlockCopy(inputBytes, 0, salt, 0, salt.Length);
            Buffer.BlockCopy(inputBytes, salt.Length, iv, 0, iv.Length);
            Buffer.BlockCopy(inputBytes, salt.Length + iv.Length, encryptedData, 0, encryptedData.Length);
            algorithm.IV = iv;
            //algorithm.Padding = PaddingMode.PKCS7;
            using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(key, salt, PBKDF2_Iterations))
            {
                algorithm.Key = pbkdf2.GetBytes(maxKeySize);
            }
            using(ICryptoTransform cryptoTransform = algorithm.CreateDecryptor())
            {
                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream(memoryStream, cryptoTransform, CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(encryptedData, 0, encryptedData.Length);
                        cryptoStream.FlushFinalBlock();                         
                    }
                    return memoryStream.ToArray();
                }
            }
        }
    }
SymmetricAlgorithmFactory returns an SymmetricAlgorithm instance
private static SymmetricAlgorithm SymmetricAlgorithmFactory(SymmetricAlgorithms symmetricAlgorithm)
    {
        switch (symmetricAlgorithm)
        {
            case SymmetricAlgorithms.AES:
                return new AesCryptoServiceProvider();
            case SymmetricAlgorithms.DES:
                return new DESCryptoServiceProvider();
            case SymmetricAlgorithms.RC2:
                return new RC2CryptoServiceProvider();
            case SymmetricAlgorithms.Rijndael:
                return new RijndaelManaged();
            case SymmetricAlgorithms.TripleDES:
                return new TripleDESCryptoServiceProvider();
            default:
                throw new Exception("The provided Symmetric algorithm is not supported.");
        }
    }
public enum SymmetricAlgorithms
{
    AES,
    DES,
    RC2,
    Rijndael,
    TripleDES
}
Extra Class properties
private static readonly RandomNumberGenerator _rng = RandomNumberGenerator.Create();
    private const int PBKDF2_SaltBytes = 8; //PBKDF2 recommends 64 bits minimum. 64 / 8 = 8 bytes
    private const int PBKDF2_Iterations = 10000;
    private static Encoding encoding = Encoding.UTF32;
Using AES to test, I then tried to change the padding property and got some different messages
PaddingMode.None - Encryption method threw exception
Blockquote System.Security.Cryptography.CryptographicException: 'The input data is not a complete block.'
PaddingMode.PKCS7 + PaddingMode.ANSIX923 + PaddingMode.ISO10126 - Decryption method threw exception
Blockquote System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.'
PaddingMode.Zeros - This seemed to work with both a correct and incorrect key
Would anyone be able to help my understanding of the padding and why certain modes fail? Would it be a situation where different padding is needed for each of the different Symmetric Algorithms?
 
    