I keep getting this \"The input data is not a complete block.\" error while decrypting. The function successfully encrypts plain text and puts the IV in a textbox. I am using t
Unless you are going to manually make sure your input is in multiples of BlockSize (in bits), make sure to specify a padding:
Example code:
byte[] Process(byte[] bInput, bool decrypt = false)
{
byte[] bOutput = null;
using (var c = System.Security.Cryptography.AesCryptoServiceProvider.Create())
{
c.BlockSize = 128;
c.IV = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; // blocksize / 8 = 16 long
c.KeySize = 256;
c.Key = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf }; // key = keysize / 8 = 32 bytes
c.Mode = System.Security.Cryptography.CipherMode.CBC;
c.Padding = System.Security.Cryptography.PaddingMode.PKCS7;
if (decrypt)
{
using (var t = c.CreateDecryptor())
{
bOutput = t.TransformFinalBlock(bInput, 0, bInput.Length);
}
}
else
{
using (var t = c.CreateEncryptor())
{
bOutput = t.TransformFinalBlock(bInput, 0, bInput.Length);
}
}
}
return bOutput;
}
There are multiple issues with your code.
In encryption function:
MemoryStream
, so it gets created with fixed size and cannot be expanded by future padding. You should use New MemoryStream(datain.Length)
instead.memorystream.Close()
is issued and then the contents of memorystream.ToArray()
is requested, — but without any explicit cstream.Close()
invocation: that way the last blocks, including padding, are not actually written to memorystream
. You should call cstream.Close()
before extracting memorystream
data.AesCryptoServiceProvider
resources before closing both CryptoStream
and MemoryStream
.In decryption function:
decrypteddata
is overestimated without taking padding into account. You should shrink this array based on the actual value returned by cryptostream.Read(…)
.AES.Clear()
as above.Return Encoding.UTF8.GetString(decrypteddata.ToArray())
instead.After fixing those issues, I could run your program without any error.
I had the same problem until I implemented with ICryptoTransform:
...
Dim AES As New AesCryptoServiceProvider
AES.Key = Encryptionkey
AES.Mode = CipherMode.CBC
AES.IV = Convert.FromBase64String(tbIV.Text)
Dim transformer As ICryptoTransform = AES.CreateDecryptor()
dim trnsfrmBlock as Byte() = transformer.TransformFinalBlock(EncryptionIn, 0, EncryptionIn.Length)
Return Convert.ToBase64String(trnsfrmBlock)