Pages

Wednesday 12 June 2013

Encrypt/Decrypt QueryString in asp.net

Introduction


We often pass values between pages in the form of a query string as key-value pairs. Query string is the easiest way and most widely practiced mechanism of transferring small pieces of data between web pages. I have observed and came across the problem with readable text/data being passed in the query string. The end-user may change the value in the query string to play around with the application, and at the same time, it leads to compromising the security and data integrity of the system.

Solution

I have worked on the problem, and developed a small code piece that encrypts and decrypts the query string with a specified key. So, the URL looks something like http://<Web Address>/Page2.aspx?Q5vcD9JTYpWVEowhCJ/PMAjkzatZ22ouiESQebrzyjx0IhRCEZigHp3YMVRwkAXD.

Using the code

In the sample application, I have developed two pages, Page1.aspx and Page2.aspx, apart from a class EncryptDecryptQueryString.cs for encryption and decryption.
Page1.aspx has three fields which the user fills in, and after the submission of the form, the values from the fields are sent across to Page2.aspx in the form of an encrypted query string. In Page2.aspx, the query string is decrypted, and the original values are retrieved to be shown in labels.
The important fact that I would like to mention is that a key is used to encrypt and decrypt the query string data.

The class - EncryptDecryptQueryString.cs

public class EncryptDecryptQueryString
{
private byte[] key = { };
private byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef };
public string Decrypt(string stringToDecrypt, string sEncryptionKey)
{
byte[] inputByteArray = new byte[stringToDecrypt.Length + 1];
try
{
key = System.Text.Encoding.UTF8.GetBytes(sEncryptionKey);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
inputByteArray = Convert.FromBase64String(stringToDecrypt);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,
des.CreateDecryptor(key, IV), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
return encoding.GetString(ms.ToArray());
}
catch (Exception e)
{
return e.Message;
}
}

public string Encrypt(string stringToEncrypt, string SEncryptionKey)
{
try
{
key = System.Text.Encoding.UTF8.GetBytes(SEncryptionKey);
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
byte[] inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt);
MemoryStream ms = new MemoryStream();
CryptoStream cs = new CryptoStream(ms,
des.CreateEncryptor(key, IV), CryptoStreamMode.Write);
cs.Write(inputByteArray, 0, inputByteArray.Length);
cs.FlushFinalBlock();
return Convert.ToBase64String(ms.ToArray());
}
catch (Exception e)
{
return e.Message;
}
}
}
 
In the class above, you will find that there are two methods, one to encrypt and the other to decrypt. Please note that the methods accept the string to encrypt or decrypt apart from the key to perform the encryption or decryption operation. This key is to be kept secret, and the same key should be used to perform both the operations.

Page1.aspx: This page has got three fields. When the user fills in data and submits the button, the data from the fields are retrieved and encrypted, and send across to Page2.aspx. Here goes the code to do so:

protected void btnSubmit_Click(object sender, EventArgs e)
{
string strName = "", strAge = "", strPhone = "";
strName = txtName.Text;
strAge = txtAge.Text;
strPhone = txtPhone.Text;
string strURL = "Page2.aspx?";
if (HttpContext.Current != null)
{
string strURLWithData = strURL +
EncryptQueryString(string.Format("Name={0}&Age={1}&Phone={2}",
strName, strAge, strPhone));
HttpContext.Current.Response.Redirect(strURLWithData);
}
else
{ }
}

public string EncryptQueryString(string strQueryString)
{
EncryptDecryptQueryString objEDQueryString = new EncryptDecryptQueryString();
return objEDQueryString.Encrypt(strQueryString, "r0b1nr0y");
}
Note in the above code snippet how the data is retrieved and encrypted using the key “r0b1nr0y”. You can use any key that is 8 characters in length for encryption, and use the same for decryption.
Page2.aspx: This page retrieves data from the URL, and decrypts the query string to get the original data. Here goes the code snipped to do so:

protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string strReq = "";
strReq = Request.RawUrl;
strReq = strReq.Substring(strReq.IndexOf('?') + 1);

if (!strReq.Equals(""))
{
strReq = DecryptQueryString(strReq);

//Parse the value... this is done is very raw format..
//you can add loops or so to get the values out of the query string...
string[] arrMsgs = strReq.Split('&');
string[] arrIndMsg;
string strName = "", strAge = "", strPhone = "";
arrIndMsg = arrMsgs[0].Split('='); //Get the Name
strName = arrIndMsg[1].ToString().Trim();
arrIndMsg = arrMsgs[1].Split('='); //Get the Age
strAge = arrIndMsg[1].ToString().Trim();
arrIndMsg = arrMsgs[2].Split('='); //Get the Phone
strPhone = arrIndMsg[1].ToString().Trim();

lblName.Text = strName;
lblAge.Text = strAge;
lblPhone.Text = strPhone;
}
else
{
Response.Redirect("Page1.aspx");
}
}
}

private string DecryptQueryString(string strQueryString)
{
EncryptDecryptQueryString objEDQueryString = new EncryptDecryptQueryString();
return objEDQueryString.Decrypt(strQueryString, "r0b1nr0y");
}
 
You can go through the attached project to get the entire solution and understand it better. Please note that the sample web application is developed using .NET 2008.

Conclusion

So, we now can send data using query strings in encrypted format and decrypt the same in the target page to get the original data. It will not be easy to tamper with the data in the query string, and hence the security and integrity of the application data is not compromised. Hope you enjoyed this article. Happy programming!!!

No comments:

Post a Comment