﻿# More on my journey into the wonderful world of ASP.NET 1.x ViewState

<datetime class="hidden">2004-02-29T00:00</datetime>
<!-- category -- mostlylucidcouk, Imported, ASP.NET, Security -->

I wrote in a [previous post](/posts/694.aspx) that I was planning to have a poke around with [ViewState](http://msdn.microsoft.com/library/en-us/cpref/html/frlrfsystemwebuicontrolclassviewstatetopic.asp), extending the stuff I've done on compression into encryption and signing etc...well there's good and bad news for this plan. It looks like (oddly) that the MAC  and encryption stuff is actually handled in the LosWriter class; an internal class used by [LosFormatter](http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemwebuilosformatterclasstopic.asp) to actually do the object serialization...it uses the following code to do this (thanks once more to the indispensible [Reflector](http://www.aisto.com/roeder/dotnet/)) :

```
internal void CompleteTransforms(TextWriter output, bool enableMac, byte[] macKey)
{ int num1;
byte[] array1;
string text1;
char[] array2;
string text2;
num1 = 0;
if (this._recyclable)
{
 this._byteBuffer = ((byte[]) LosWriter._byteBufferAllocator.GetBuffer());
if (this._freePos > 0)
{
 num1 = Encoding.UTF8.GetBytes(this._charBuffer, 0, this._freePos, this._byteBuffer, 0);
 
}
if (enableMac)
{
 array1 = MachineKey.GetEncodedData(this._byteBuffer, macKey, 0, &(num1));
text1 = Convert.ToBase64String(array1, 0, num1);
output.Write(text1);
return; 
}
array2 = ((char[]) LosWriter._charBufferAllocatorBase64.GetBuffer());
num1 = Convert.ToBase64CharArray(this._byteBuffer, 0, num1, array2, 0);
output.Write(array2, 0, num1);
LosWriter._charBufferAllocatorBase64.ReuseBuffer(array2);
return; 
}
this._byteBuffer = Encoding.UTF8.GetBytes(this._charBuffer, 0, this._freePos);
num1 = this._byteBuffer.Length;
if (enableMac)
{
 this._byteBuffer = MachineKey.GetEncodedData(this._byteBuffer, macKey, 0, &(num1));
 
}
text2 = Convert.ToBase64String(this._byteBuffer);
output.Write(text2);
 
}
```

As you can probably see, this code handles the application of the MAC key  and encryption to the serialized data. This is the code used by the 'MachineKey' to perform the encryption:

```
internal static byte[] EncryptOrDecryptData(bool fEncrypt, byte[] buf, byte[] modifier, int start, int length)
{ MemoryStream stream1;
ICryptoTransform transform1;
CryptoStream stream2;
byte[] array1;
byte[] array2;
MachineKey.EnsureConfig();
stream1 = new MemoryStream();
transform1 = MachineKey.GetCryptoTransform(fEncrypt);
stream2 = new CryptoStream(stream1, transform1, 1);
stream2.Write(buf, start, length);
if (fEncrypt && (modifier != null))
{
 stream2.Write(modifier, 0, modifier.Length);
 
}
stream2.FlushFinalBlock();
array1 = stream1.ToArray();
stream2.Close();
MachineKey.ReturnCryptoTransform(fEncrypt, transform1);
if (!fEncrypt && (modifier != null))
{
 array2 = new byte[((uint) (array1.Length - modifier.Length))];
Buffer.BlockCopy(array1, 0, array2, 0, array2.Length);
array1 = array2;
 
}
return array1; 
} 
```

Unfortunately, this means I'll either have to play about with reflection / dump the source from Refelector / completely reinvent how this works to go much further with my ViewState tinkering, god it'd have been nice if this stuff were done with a Factory originally...guess they didn't think anyone would be nuts enough to want to play with it...:-)

I'm eventually going to have to relent and actually write an article one of these days...problem for me is structuring the thing so it's readable to non-obsessive humans...