为什么 RijndaelManaged 引发以下异常:填充无效且无法删除?

Why RijndaelManaged raises the following exception: Padding is invalid and cannot be removed?

在.NET4/C#应用程序中,我有以下加密方式:

        public static byte[] Encrypt(byte[] data, byte[] key, out byte[] iv)
        {
            byte[] encryptedData;
            using (var aes = new RijndaelManaged()
            {
                Padding = PaddingMode.PKCS7,
                Mode = CipherMode.CBC,
                KeySize = KEY_SIZE,
                BlockSize = BLOCK_SIZE
            })
            {
                aes.GenerateIV();
                var encryptor = aes.CreateEncryptor(key, aes.IV);

                using (var msEncrypt = new MemoryStream())
                {
                    using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        csEncrypt.Write(data, 0, data.Length);
                        csEncrypt.FlushFinalBlock();
                    }
                    encryptedData = msEncrypt.ToArray();
                }
                iv = new byte[aes.IV.Length];
                aes.IV.CopyTo(iv, 0);
            }
            return encryptedData;
        }

        public static byte[] Encrypt(byte[] data, string sKey, out byte[] iv)
        {
            return Encrypt(data, Encoding.UTF8.GetBytes(sKey), out iv);
        }

以及以下解密方式:

        public static byte[] Decrypt(byte[] encryptedData, byte[] key, byte[] iv)
        {
            byte[] data;
            using (var aes = new RijndaelManaged()
            {
                Padding = PaddingMode.PKCS7,
                Mode = CipherMode.CBC,
                KeySize = KEY_SIZE,
                BlockSize = BLOCK_SIZE
            })
            {
                var decryptor = aes.CreateDecryptor(key, iv);
                using (var msData = new MemoryStream())
                {
                    using (var csEncrypt = new CryptoStream(msData, decryptor, CryptoStreamMode.Read))
                    {
                        csEncrypt.Read(encryptedData, 0, encryptedData.Length);
                    }
                    data = msData.ToArray();
                }
            }
            return data;
        }

        public static byte[] Decrypt(byte[] encryptedData, string sKey, byte[] iv)
        {
            return Decrypt(encryptedData, Encoding.UTF8.GetBytes(sKey), iv);
        }

我写了这个单元测试。

        [TestMethod]
        public void TestEncryptDecryptBytes()
        {
            Random rnd = new Random(666);
            string key = "ABCDEFGHABCDEFGHABCDEFGHABCDEFGH";

            //Run 100 times
            for (int i = 0; i < 100; i++)
            {
                byte[] buf = new byte[rnd.Next(100, 1024)];
                rnd.NextBytes(buf);
                byte[] iv;
                var enc = Crypto.Encrypt(buf, key, out iv);
                var dec = Crypto.Decrypt(enc, key, iv);
                Assert.AreEqual(buf.Length, dec.Length);
                for (int j = 0; j < buf.Length; j++)
                {
                    Assert.AreEqual(buf[j], dec[j]);
                }
            }
        }

我在解密加密数据时遇到以下异常。

System.Security.Cryptography.CryptographicException: Padding is invalid and cannot be removed.

不知道哪里出了问题。我很确定密钥和 IV 在加密和解密过程中是相同的。块大小和密钥大小也相同。感谢任何帮助。

您对数据的解密有误。试试这个:

public static byte[] Decrypt(byte[] encryptedData, byte[] key, byte[] iv)
{
    byte[] data;
    using (var aes = new RijndaelManaged()
    {
        Padding = PaddingMode.PKCS7,
        Mode = CipherMode.CBC,
        KeySize = KEY_SIZE,
        BlockSize = BLOCK_SIZE
    })
    {
        var decryptor = aes.CreateDecryptor(key, iv);

        using (var encStream = new MemoryStream(encryptedData))
        {
            using (var csDecrypt = new CryptoStream(encStream, decryptor, CryptoStreamMode.Read))
            {
                using (var msData = new MemoryStream())
                {
                    csDecrypt.CopyTo(msData);
                    data = msData.ToArray();
                }
            }
        }
    }
    return data;
}