【问题标题】:Why RijndaelManaged raises the following exception: Padding is invalid and cannot be removed?为什么 RijndaelManaged 会引发以下异常:Padding is invalid and cannot be removed?
【发布时间】:2022-01-03 07:37:05
【问题描述】:

在 .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 是相同的。块大小和密钥大小也相同。任何帮助表示赞赏。

【问题讨论】:

  • 你忽略了Read的返回值...

标签: c# .net cryptography aes


【解决方案1】:

您对数据的解密不正确。试试这个:

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;
}

【讨论】:

  • 你能详细说明我做错了什么吗?谢谢!
  • 您创建了一个空的MemoryStream,将其包装在CryptoStream 中,并尝试将其读取到encryptedData 数组中。所以实际上你做了与你需要做的相反的事情。
  • 知道了。再次感谢。
猜你喜欢
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多