I'm studying AES with C# and wrote some codes to encrypt string. At first, it throws exception below.
System.Security.Cryptography.CryptographicException: 'Padding is invalid and cannot be removed.'
I solved this by setting padding mode for encryption/decryption as 'None'.
And then, I put some spaces before/after the string to be encrypted. Then, I get below exception.
System.Security.Cryptography.CryptographicException: 'The input data is not a complete block.'
So, I removed padding setting for encryption. And then, everything looks okay.
My questions are
Thanks in advance.
public void ByteEncryption()
{
byte[] key = new byte[16];
byte[] iv = new byte[16];
for (int ii = 0; ii < 16; ii++)
{
key[ii] = (byte)ii;
iv[ii] = (byte)ii;
}
string str_data = " This is a string to be encrypted ";
byte[] data = Encoding.Unicode.GetBytes(str_data);
byte[] encrypted = EncryptMemory(data, key, iv);
foreach(byte b in encrypted)
Console.WriteLine(b);
string str_encrypted = Encoding.Unicode.GetString(encrypted);
Console.Write("Encrypted:");
Console.WriteLine(str_encrypted);
byte[] decrypted = DecryptMemory(encrypted, key, iv);
string str_decrypted = Encoding.Unicode.GetString(decrypted);
Console.Write("---");
Console.Write(str_decrypted);
Console.WriteLine("---");
}
byte[] EncryptMemory(byte[] data, byte[] key, byte[] iv)
{
using (SymmetricAlgorithm algorithm = Aes.Create())
{
algorithm.Padding = PaddingMode.None; // Throw exception
using (ICryptoTransform encryptor = algorithm.CreateEncryptor(key, iv))
{
return Crypt(data, encryptor);
}
}
}
byte[] DecryptMemory(byte[] data, byte[] key, byte[] iv)
{
using (SymmetricAlgorithm algorithm = Aes.Create())
{
algorithm.Padding = PaddingMode.None;
using (ICryptoTransform decryptor = algorithm.CreateDecryptor(key, iv))
{
return Crypt(data, decryptor);
}
}
}
byte[] Crypt(byte[] data, ICryptoTransform cryptor)
{
using (MemoryStream memory = new MemoryStream())
using (CryptoStream stream = new CryptoStream(memory, cryptor, CryptoStreamM ode.Write))
{
stream.Write(data, 0, data.Length);
return memory.ToArray();
}
}
From this link, after reading cadrell0's comment below,
Good call on Dispose. I was calling ms.ToArray() before disposing CryptoStream. Moving that line outside of the using fixed it for me
I solved the problem. This had been torturing me for 2 days. Answering my questions, all the misunderstanding came from the length of the string I was encrypting. By inserting random number of characters, the length of input string without special character was exactly multiple of 16 accidently; Size of unicode is 16 bit. The original string without special character didn't need a padding as it was already multiple of 16.