C# AES字节数组加解密报错:输入数据不是完整块
Hey, let's break down why you're hitting that frustrating error and fix your AES code step by step.
Key Issues in Your Current Code
Encryption: Missing Final Block Flush
AES is a block cipher, meaning it processes data in fixed-size 128-bit blocks in your case. When your plaintext isn't a multiple of the block size, the algorithm adds padding to make it fit. Your current encryption code doesn't properly finalize theCryptoStream, so the padding never gets written to the output—resulting in an incomplete ciphertext that fails during decryption.Decryption: Incorrect Buffer Offset
In your decryption loop, you're usingtotalReadas the offset when writing toplainStream, which is wrong. EachcryptoStream.Readwrites data to the start ofbuffer, so you should always use0as the offset instead oftotalRead.
Corrected Encryption Code
public static byte[] MyEnc(byte[] Input) { using (MemoryStream mstream = new MemoryStream()) { using (AesCryptoServiceProvider encdec = new AesCryptoServiceProvider()) { encdec.BlockSize = 128; encdec.KeySize = 256; encdec.Key = ASCIIEncoding.ASCII.GetBytes(Key); encdec.IV = ASCIIEncoding.ASCII.GetBytes(IV); // Explicitly set padding mode (PKCS7 is default, but clarity helps) encdec.Padding = PaddingMode.PKCS7; ICryptoTransform icrypt = encdec.CreateEncryptor(encdec.Key, encdec.IV); using (CryptoStream cryptoStream = new CryptoStream(mstream, icrypt, CryptoStreamMode.Write)) { cryptoStream.Write(Input, 0, Input.Length); // Ensure all data (including padding) is written to the stream cryptoStream.FlushFinalBlock(); } } return mstream.ToArray(); } }
Corrected Decryption Code
public static byte[] MyDec(byte[] Input) { using (MemoryStream plainStream = new MemoryStream()) { using (MemoryStream mStream = new MemoryStream(Input)) { using (AesCryptoServiceProvider encdec = new AesCryptoServiceProvider()) { encdec.BlockSize = 128; encdec.KeySize = 256; encdec.Key = ASCIIEncoding.ASCII.GetBytes(Key); encdec.IV = ASCIIEncoding.ASCII.GetBytes(IV); encdec.Padding = PaddingMode.PKCS7; ICryptoTransform icrypt = encdec.CreateDecryptor(encdec.Key, encdec.IV); using (CryptoStream cryptoStream = new CryptoStream(mStream, icrypt, CryptoStreamMode.Read)) { byte[] buffer = new byte[4096]; // Larger buffer is more efficient int read; while ((read = cryptoStream.Read(buffer, 0, buffer.Length)) > 0) { // Write from the start of the buffer, not totalRead plainStream.Write(buffer, 0, read); } } } return plainStream.ToArray(); } } }
Additional Notes
- Ciphertext Length: After fixing the encryption, your ciphertext will be longer than the plaintext (due to padding)—this is normal! AES requires padding for data that doesn't fit exactly into block sizes, so you can't expect plaintext and ciphertext to be the same length. Your original assumption that they'd match was part of the problem.
- Encoding Warning: Using
ASCIIEncodingfor your key/IV can cause issues if your key/IV contains non-ASCII characters. Consider usingUTF8Encodingor converting your key/IV from a base64 string instead to avoid data loss. - Resource Disposal: I cleaned up the using blocks to ensure all resources are properly disposed, which avoids potential memory leaks.
内容的提问来源于stack exchange,提问作者Edward

