简体   繁体   English

C#:AES错误:填充无效,无法删除。 相同的钥匙和一切,帮助

[英]C#: AES error: Padding is invalid and cannot be removed. Same key and everything, help

I'm quite new to C# so please be patient with me. 我对C#很陌生,所以请耐心等待我。 I know this question was asked a lot if times, but I couldn't find an answer to my problem. 我知道这个问题在很多时候被问了很多,但是我找不到问题的答案。

I'm saving some data and before writing it to a file I convert it to binary and store it in array, which I encrypt and then write to file. 我正在保存一些数据,在将其写入文件之前,我将其转换为二进制文件并将其存储在数组中,我将其加密然后写入文件。 I encrypt data in chunks (32 bytes). 我以块(32字节)加密数据。 In the same way I read data in chunks of 32 bytes and then decrypt that data and then this should repeat till the end of file. 以同样的方式,我以32字节的块读取数据,然后解密该数据,然后这应该重复,直到文件结束。 But when it comes to decryption the following error is thrown: 但是当涉及到解密时,会抛出以下错误:

Padding is invalid and cannot be removed. 填充无效,无法删除。

I use the same key and iv (hardcoded just until I get it working) 我使用相同的密钥和iv(硬编码直到我工作)

Here is my encryption code, which works without problems: 这是我的加密代码,没有问题:

        //result
        byte[] data = new byte[32];

        //setup encryption (AES)
        SymmetricAlgorithm aes = Aes.Create();
        byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9,50};
        byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
        ICryptoTransform encryptor = aes.CreateEncryptor(key, iv);

        FileStream fStream = new FileStream(file, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Read, 1024, false);

        //prepare data to write (byte array 'data') ...

        //encrypt
               MemoryStream m = new MemoryStream();
               using (Stream c = new CryptoStream(m, encryptor, CryptoStreamMode.Write))
                   c.Write(data, 0, data.Length);
               data = m.ToArray();
               fStream.Write(data, 0, data.Length);

And here is my decryption code: 这是我的解密代码:

FileStream fStream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, false);

            //setup encryption (AES)
            SymmetricAlgorithm aes = Aes.Create();
            byte[] key = { 145, 12, 32, 245, 98, 132, 98, 214, 6, 77, 131, 44, 221, 3, 9, 50 };
            byte[] iv = { 15, 122, 132, 5, 93, 198, 44, 31, 9, 39, 241, 49, 250, 188, 80, 7 };
            ICryptoTransform decryptor = aes.CreateDecryptor(key, iv);

            //result
            byte[] data = new byte[32];

            //loop for reading the whole file ...
            int len = fStream.Read(data, 0, 32);

            //decrypt
                MemoryStream m = new MemoryStream();
                using (Stream c = new CryptoStream(m, decryptor, CryptoStreamMode.Write))
                    c.Write(data, 0, data.Length); //The exception is thrown in this line                  
                data = m.ToArray();

                //using the decrypted data and then looping back to reading and decrypting...

I tried all I could think of (which is not much because I'm very new to cryptography), I searched everywhere and I couldn't find a solution to my problem. 我尝试了所有我能想到的(这不是很多,因为我对密码学很新),我到处搜索,我找不到解决问题的方法。 I also helped myself with the book C# in a Nutshell . 我还在Nutshell中帮助自己学习了C#这本书。

If anyone has ideas on why this could happen I'll be really thankful because I have no ideas. 如果有人知道为什么会发生这种情况我会非常感激,因为我没有想法。

Thank you for your time and answers. 谢谢你的时间和答案。

EDIT: It seems that the size of the encrypted data is 48 bytes (12 bytes more than the original). 编辑:似乎加密数据的大小是48字节(比原始数据多12个字节)。 Why is that so? 为什么会这样? I thought that it only adds bytes if they are not a multiple of the block size (16 bytes, my data is 32 bytes). 我认为如果它们不是块大小的倍数(16字节,我的数据是32字节),它只会添加字节。 Is data always larger, and with constant increase (I need to know that in order to properly read and decrypt). 数据总是更大,并且不断增加(我需要知道为了正确读取和解密)。

Note: I can't directly use other streams because I need to have control over the output format and I believe it is also safer and faster to encrypt in memory. 注意:我不能直接使用其他流,因为我需要控制输出格式,我相信它在内存中加密也更安全,更快。

Based on your edit: 根据您的编辑:

EDIT: It seems that the size of the encrypted data is 48 bytes (12 bytes more than the original). 编辑:似乎加密数据的大小是48字节(比原始数据多12个字节)。 Why is that so? 为什么会这样? I thought that it only adds bytes if they are not a multiple of the block size (16 bytes, my data is 32 bytes). 我认为如果它们不是块大小的倍数(16字节,我的数据是32字节),它只会添加字节。 Is data always larger, and with constant increase (I need to know that in order to properly read and decrypt). 数据总是更大,并且不断增加(我需要知道为了正确读取和解密)。

If the encrypted data is 48 bytes, thats 16 bytes larger than your original array. 如果加密数据是48个字节,那比原始数组大16个字节。 This makes sense because the algorithm with pad the data because the default is PKCS7 (even if the size matches the block size, because it pads to the next multiple of the block-size). 这是有道理的,因为算法使用填充数据,因为默认值是PKCS7 (即使大小与块大小匹配,因为它填充到块大小的下一个倍数)。 If you wish to keep it exactly 32 bytes, just change the Padding to None 如果您希望将其保留为32个字节,只需将Padding更改为None

aes.Padding = PaddingMode.None;

You seem to be treating the length of the plaintext as the length of the ciphertext. 您似乎将明文的长度视为密文的长度。 That's not a safe assumption. 这不是一个安全的假设。

Why are you copying between FileStream and MemoryStream , you can pass a FileStream directly to the encryptor/decryptor. 为什么要在 FileStreamMemoryStream之间进行复制,可以将 FileStream直接传递给encryptor / decryptor。

In PKCS7, there is a minimum of one padding byte (to store the number of padding bytes). 在PKCS7中,至少有一个填充字节(用于存储填充字节数)。 So the output size will be Ceil16(input.Length + 1) , or (input.Length & ~15) + 1 . 因此输出大小为Ceil16(input.Length + 1)(input.Length & ~15) + 1

The short of it is that AES encrypts messages in blocks of 16 bytes. 缺点是AES以16字节的块加密消息。 If your message isn't an even multiple of 16 bytes, the algorithm needs to be a little different for the last block; 如果您的消息不是16字节的偶数倍,则最后一个块的算法需要稍微不同; specifically, the last block must be "padded" with a value known to the algorithm as a padding value (usually zero, sometimes something else like a space character value). 具体来说,最后一个块必须用算法已知的值“填充”作为填充值(通常为零,有时候像空格字符值一样)。

You're doing that yourself, by putting the data into a fixed-length byte array. 你是通过将数据放入一个固定长度的字节数组中自己做的。 You padded the data yourself, but the decrypter is now attempting to de-pad the last block and getting byte values it doesn't recognize as the padding that its encrypter counterpart would have added. 您自己填充了数据,但是解密器现在正在尝试对最后一个块进行解填,并获取它不能识别为其加密器对应物将添加的填充的字节值。

The key is not to pad the message. 关键是不填充消息。 You can use the BitConverter class to cast byte arrays to and from IConvertible types (value types and strings), and then use that instead of rolling your own byte array. 您可以使用BitConverter类将字节数组转换为IConvertible类型(值类型和字符串),然后使用它来代替滚动您自己的字节数组。 Then, when you decrypt, you can read from the decryption stream up to the ciphertext length, but don't expect there to be that many actual bytes in the decrypted result. 然后,当您解密时,您可以从解密流中读取密文长度,但不要指望解密结果中存在那么多实际字节。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 c# AES 解密错误并显示“填充无效且无法删除”。 - c# AES decryption errors with “Padding is invalid and cannot be removed.” 填充无效,无法删除。 c#解密AES Rijndael,AES托管 - Padding is invalid and cannot be removed. c# decrypt AES Rijndael, AES Managed 解密AES给我“填充无效,无法删除。”错误 - Decrypting AES gives me “Padding is invalid and cannot be removed.” error 使用Crypto-JS和C#解密的AES加密-避免“填充无效且无法删除。” - AES encryption with Crypto-JS and C# Decryption - avoiding “Padding is invalid and cannot be removed.” TRIPLEDES 填充无效且无法删除。 c#解密 - TRIPLEDES padding is invalid and cannot be removed. c# decrypt “填充无效,无法删除。”出现错误 - “Padding is invalid and cannot be removed.” error with a twist 不断收到“CryptographicException: Padding is invalid and cannot be removed”。 即使有填充,AES CBC 加密也会出错 - Keep getting “CryptographicException : Padding is invalid and cannot be removed.” errors with AES CBC encryption even with padding AES Android加密C#解密填充无效,无法删除 - AES Android Encryption C# decryption Padding is invalid and cannot be removed 填充无效,无法删除。 Rjindaal加密 - Padding is invalid and cannot be removed. Rjindaal encryption AES加密错误:填充无效,无法删除 - AES Encryption Error: Padding is invalid and cannot be removed
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM