|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionWorking with cookies in ASP.NET is a trivial task. However, the security of information traveling back and forth is non-existent. Basically, any casual hacker could view and change this plain text cookie. This project addresses this need to possibly protect that cookie data from the occasional hacker. Note that the security implemented here is most likely only as durable as the ASP.NET ViewState's encryption. I believe their encryption is based on a hash plus the actual data encrypted, so that if you try to change the data, it's pretty difficult. ASP.NET's ViewState uses the So this would be tamper-evident security, but when the actual data itself isn't that sensitive, like the user's current ID or something similar. So note that I'm not guaranteeing that the data in the encrypted cookie can't be read, so don't store anything sensitive in there! You've been warned [cue fast lawyer talk]. Working with HttpCookieEncryptionYou basically reference the DLL or include the code in your project. The Simply make a call to On the next request, you can decrypt the encrypted cookie by calling void Page_Load(object sender,EventArgs e)
{
HttpCookie myEncryptedCookie =
HttpCookieEncryption.Decrypt(this.Context,"myEncryptedCookie");
if(myEncryptedCookie==null)
{
//cookie didnt exist, probably first request,
//this is normally a login redirect or something?
HttpCookie test = Response.Cookies["myEncryptedCookie"];
//always returns an instance
test["key1"]="value1";
test["key2"]="value2";
HttpCookieEncryption.Encrypt(this.Context,"myEncryptedCookie");
//updates the Response, so subsequent calls to the cookie's value will
//yield the encrypted hex string, so if you lose the reference
//to the decrypted instance, just call HttpCookieEncryption.Decrypt
HttpCookie decrypted = HttpCookieEncryption.Decrypt(this.Context,
"myEncryptedCookie");
//note that decrypt NEVER updates the Response Cookie in memory.
//these will be equal
if(test["key1"].Equals(decrypted["key1"]) &&
test["key2"].Equals(decrypted["key2"]))
//symmetric algorithm magic
else
//should never happen.
}
}
How it worksThe most important part is utilizing ASP.NET's built in Reflection APIs are used to get a pointer to key methods used internally by the private static MethodInfo _encOrDecData;
private static MethodInfo _hexStringToByteArray;
private static MethodInfo _byteArrayToHexString;
static MachineKeyWrapper()
{
object config = HttpContext.Current.GetConfig("system.web/machineKey");
Type configType = config.GetType();
Type machineKeyType =
configType.Assembly.GetType("System.Web.Configuration.MachineKey");
if (machineKeyType == null)
{
// try to get asp.net 2.0 type
machineKeyType =
configType.Assembly.GetType("System.Web.Configuration.MachineKeySection");
}
BindingFlags bf = BindingFlags.NonPublic | BindingFlags.Static;
_encOrDecData = machineKeyType.GetMethod("EncryptOrDecryptData", bf);
_hexStringToByteArray = machineKeyType.GetMethod("HexStringToByteArray", bf);
_byteArrayToHexString = machineKeyType.GetMethod("ByteArrayToHexString", bf);
//is there any way to get some kind of pointer? or just trust:
// MethodBase.Invoke
// RuntimeMethodInfo.Invoke
// RuntimeMethodHandle.InvokeFast
// RuntimeMethodHandle._InvokeFast
// ...lot of extra calls...
if( _encOrDecData==null ||
_hexStringToByteArray==null || _byteArrayToHexString==null )
{
throw new
InvalidOperationException("Unable to get the methods to invoke.");
}
}
The public static byte[] HexStringToByteArray(string str)
{
return (byte[]) _hexStringToByteArray.Invoke(null,
new object[] { str });
}
public static string ByteArrayToHexString(byte[] array, int length)
{
return (string) _byteArrayToHexString.Invoke(null,
new object[] { array, length });
}
public static byte[] EncryptOrDecryptData(bool encrypting,
byte[] data, byte[] mod, int index, int length)
{
return (byte[])_encOrDecData.Invoke(null,
new object[] { encrypting, data, mod, index, length });
}
Some caveatsObviously, since we've used Reflection to obtain handles to the internal void Page_Load(object sender,EventArgs e)
{
HttpCookie userDetails = HttpCookieSecurity.Decrypt(this.Context,"userdetails");
SomeRoutineUsingCookie(userDetails);
}
void SomeRoutineUsingCookie(HttpCookie userDetails)
{
this.lblFirstName.Text = userDetails["FirstName"];
this.lblLastName.Text = userDetails["LastName"];
this.lblUserId.Text = userDetails["Id"];
}
Where do we go from here?
My new article about updating CookieParameter builds on the existing
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||