• 9
• 9
• 10
• 10
• 11

# AesManaged error (WITH CODE)

## Recommended Posts

Alright, you asked for it, and here it is.  I run this to encrypt and decrypt (depending on the mode enumeration variable).
Encryption works fine, and outputs seemingly random data, but decryption throws an exception when I try to set the cs.Position = 0.  The exception looks like this:

'cs.Position' threw an exception of type 'System.NotSupportedException'

But even if I disable that line, although I don't get an exception, buffer fills with only zeros.

I've tried to change the padding mode and the cipher mode, but that doesn't fix it either.  Here's the code:

public byte[] aes(byte[] data, byte[] key, EncryptionMode mode)
{
byte[] result = null;
AesManaged aesm = new AesManaged();
aesm.BlockSize = 128;
aesm.KeySize = 256;
aesm.IV = new byte[16];
aesm.Key = key;
aesm.Mode = CipherMode.ECB;
if(mode == EncryptionMode.Encrypt)
{
ICryptoTransform encryptor = aesm.CreateEncryptor(aesm.Key, aesm.IV);
using(MemoryStream ms = new MemoryStream())
{
using(CryptoStream cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write))
{
using(StreamWriter sw = new StreamWriter(cs))
{
sw.Write(data);
}
result = ms.ToArray();
}
}
}
else
{
ICryptoTransform decryptor = aesm.CreateDecryptor(aesm.Key, aesm.IV);
using(MemoryStream ms = new MemoryStream())
{
ms.Position = 0;
using(CryptoStream cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read))
{
cs.Position = 0;
{
char[] buffer = new char[16];
result = new byte[16];
for(int i = 0; i < 16; i++)
{
result = Convert.ToByte(buffer);
}
}
}
}
}
return result;
}

##### Share on other sites
The EncryptionMode.Decrypt logic doesnâ€™t initialize the decoding stream with the data provided by the argument. According to MemoryStream(byte[]) it should read something like:

ICryptoTransform decryptor = aesm.CreateDecryptor(aesm.Key, aesm.IV);
using(MemoryStream ms = new MemoryStream(data))
{


##### Share on other sites

fastcall22 is right, you're missing a parameter.  To make it a little less complicated though, try this instead.

if(mode == EncryptionMode.Encrypt)
{
System.Security.Cryptography.ICryptoTransform encryptor = aesm.CreateEncryptor(aesm.Key, aesm.IV);
result = encryptor.TransformFinalBlock(data, 0, data.Length);
}
else
{
System.Security.Cryptography.ICryptoTransform decryptor = aesm.CreateDecryptor(aesm.Key, aesm.IV);
result = decryptor.TransformFinalBlock(data, 0, data.Length);
}
Edited by Rattrap

##### Share on other sites

The other thing is your code is byte[] -> byte[].  The code on MSDN is string -> byte[] and byte[] -> string.  So just fixing that parameter doesn't fix the issue either.  When I did that with your code, it was passing the type name (System.Byte[]) to decryptor.  I'm assuming it took the input parameter and applied toString to it, returning the type name instead of the data itself.

Edited by Rattrap

##### Share on other sites

Well thanks, I can't believe I forgot the parameter!  Now it sort of works, but whatever I encrypt, when I decrypt it I get back bytes that literally translate into the string "System.Byte[]", so something is somehow not converting correctly.  The code looks fine to me!

Oh, sorry, you're already addressing that issue.  I should have refreshed the page.  Let me see what I'm doing in terms of any "ToString" calls or anything like that...

Edited by myvraccount

##### Share on other sites

I think your problem is actually in the encryptor, not the decryptor now.

sw.Write(data);

StreamWriter.Write takes a string, not byte[] (as mentioned before, their code was built around strings, not byte arrays). So I think your getting an implicit call to data.toString.

I still recommend just using the TransformFinalBlock, but to fix the existing code just take out the StreamWriter and write directly from the CryptoStream.

System.Security.Cryptography.ICryptoTransform encryptor = aesm.CreateEncryptor(aesm.Key, aesm.IV);
using(System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
using(System.Security.Cryptography.CryptoStream cs = new System.Security.Cryptography.CryptoStream(ms, encryptor, System.Security.Cryptography.CryptoStreamMode.Write))
{
cs.Write(data, 0, data.Length);
result = ms.ToArray();
}
}
Edited by Rattrap

##### Share on other sites

Oh, I see.  I was having trouble finding the call, and no wonder, if it was implicit.  But now I'm using the TransformFinalBlock, and it's working great.  Thanks!

##### Share on other sites

I don't have anything to add when it comes to the actual problem at hand (which seems to have been resolved now), but good on you for coming back with actual code :)