How to Encrypt Query String Parameters in ASP.NET
There are some circumstances when you need to encrypt query string parameters in your URLs in order to secure your web applications. There are many reasons and many cases but as one of my recent experiences in Waegis a user activation requires such a system. The reason is to prevent anyone to use other’s plain email address to activate his or her account without receiving the activation mail!
Of course, there are some solutions and I’m not using this solution on Waegis (I replaced the solution with a simpler and secure mathematical algorithm that I inspired myself) but the incoming solution is the most common way to encrypt your query string parameters.
The basic idea of this method is using DES cryptography system to encrypt query string parameters on one side and then decrypting it on the other side. But the key point about this method is that DES algorithm is a symmetric algorithm that requires two keys. How do you want to work around this?
You may want to pass your sector vector or initialization vector as a secondary parameter in query string and keep the other key private but this is an insecure solution because having those two parameters, your key is predictable so your algorithm is breakable!
But what’s the solution? The solution is to define both keys on your side and use them to encrypt your text and only pass the encrypted text to query string then retrieve the text and decrypt it with these keys.
Having this background, the implementation is easy and straightforward and contains nothing but some .NET cryptography code.
The main part of this workflow is building a simple cryptographic class that manages the encryption and decryption of string values with your keys. Below code represents the class that you can port for your application. There are two fields that define and hold sector vector and initialization vector. You need to define them once and add them to your application. The rest of the code should be familiar to you because it’s just a set of regular .NET cryptography operations.
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Text;
using System.Security.Cryptography;
using System.IO;
namespace QueryStringEncryption
{
public class Cryptography
{
#region Fields
private static byte[] key = { };
private static byte[] IV = { 38, 55, 206, 48, 28, 64, 20, 16 };
private static string stringKey = "!5663a#KN";
#endregion
#region Public Methods
public static string Encrypt(string text)
{
try
{
key = Encoding.UTF8.GetBytes(stringKey.Substring(0, 8));
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
Byte[] byteArray = Encoding.UTF8.GetBytes(text);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream,
des.CreateEncryptor(key, IV), CryptoStreamMode.Write);
cryptoStream.Write(byteArray, 0, byteArray.Length);
cryptoStream.FlushFinalBlock();
return Convert.ToBase64String(memoryStream.ToArray());
}
catch (Exception ex)
{
// Handle Exception Here
}
return string.Empty;
}
public static string Decrypt(string text)
{
try
{
key = Encoding.UTF8.GetBytes(stringKey.Substring(0, 8));
DESCryptoServiceProvider des = new DESCryptoServiceProvider();
Byte[] byteArray = Convert.FromBase64String(text);
MemoryStream memoryStream = new MemoryStream();
CryptoStream cryptoStream = new CryptoStream(memoryStream,
des.CreateDecryptor(key, IV), CryptoStreamMode.Write);
cryptoStream.Write(byteArray, 0, byteArray.Length);
cryptoStream.FlushFinalBlock();
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
catch (Exception ex)
{
// Handle Exception Here
}
return string.Empty;
}
#endregion
}
}
Now the rest of this post exemplify how to use this Cryptography class. I implement a UserActivation class that manages the activation process. It generates activation links by getting a username and also activates a user by getting the encrypted username key. The final class is shows below.
using System;
using System.Data;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.IO;
namespace QueryStringEncryption
{
public static class UserActivation
{
#region Public Methods
public static void ActivateUser(string key)
{
string username = Cryptography.Decrypt(key);
// TODO: Activation Login
}
public static string GetActivationLink(string username)
{
string key = Cryptography.Encrypt(username);
StringWriter writer = new StringWriter();
HttpContext.Current.Server.UrlEncode(key, writer);
return string.Format("/default.aspx?key={0}", writer.ToString());
}
#endregion
}
}
Here the important point is to not forget to UrlEncrypt the encrypted key because usually it contains some characters that will be ignored by ASP.NET and can cause exceptions on decryption.
I finally wrap up this example by applying it in a simple page. This page generates an activation link when there is no query string parameter and it also decrypts the key parameter when it is provided. In real world scenarios you can use this decrypted username to activate the user’s account.
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
namespace QueryStringEncryption
{
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(Request["key"]))
Response.Write(UserActivation.GetActivationLink("keyvannayyeri"));
else
Response.Write(Cryptography.Decrypt(Request["key"]));
}
}
}
Here are two snapshots to show how this example works.
You can download the source code sample for this post from here.
[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.
10 Comments : 07.28.08
Feedbacks
Trackback
ASP.NET How to Encrypt Query String Parameters in ASP.NET [Via: Keyvan Nayyeri ] Using client templates,...
Link Listing - July 31, 2008
This has got to be the dumbest idea ever. You should NEVER EVER need to encrypt a query string because NO CRITICAL information should EVER be passed via GET or POST.
God, it's no wonder websites are so easy to break into nowadays.
@Kris
And you're the dumbest guy who can leave such stupid comments :-D
Dear I used to download your code... it give me error on Default file
Could not load type 'QueryStringEncryption._Default'.
I also try be renaming it but its not working .... plz if u have some solution u can tell me
Aqui enumero los posibles metodos de pasaje de datos entre paginas ASP.NET ya sea en el cliente o en
Hi there,
Nice code Keyvan but when i try to Decrypt my encrypted string I get this message:
"Invalid character in a Base-64 string"
Do you know how is that possible??
Thanks
Payam
Hi,
This piece of code is quite useful but there is a problem with it.
It produces some encrypted strings which contain + character
This character makes a lot of problem when using querystrings.
For example if you have a querystring like ?id=weqSzS+sq
when you write
string strID = Request.QueryString["id"];
strID will contain 'weqSzS sq' and + character would be omitted.
It took me quite a long time to find the problem.
Anyway thanks for sharing this code:)

#1
Reflective Perspective - Chris Alcock » The Morning Brew #146
07.29.2008 @ 2:21 AM
Pingback from Reflective Perspective - Chris Alcock » The Morning Brew #146