Keyvan Nayyeri

My daily musings about software and technology

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.

How to Encrypt Query String Parameters in ASP.NET

How to Encrypt Query String Parameters in ASP.NET

You can download the source code sample for this post from here.

38 Comments

Kris
Oct 14, 2008 7:24 AM
#

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.


Keyvan Nayyeri
Oct 14, 2008 7:31 AM
#

@Kris

And you're the dumbest guy who can leave such stupid comments :-D


Nasir
Oct 15, 2008 4:38 AM
#

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


Payam
Oct 22, 2008 6:25 AM
#

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


Benjamin
Dec 19, 2008 11:22 AM
#

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:)


kp
Feb 12, 2009 6:46 PM
#

Use Server.URLEncode/Decode before encrypting/decrypting to avoid the base64 errors.


Taher
Feb 14, 2009 12:54 AM
#

Hi everyone. I am facing a problem. Assume that i have a query string like this.

default.aspx?userid=1&username=a&location=b

I wanted to encrypt everything in one... i.e all the three parameters in a single encrypted string. But on the receiving side.. how will i use Request.QueryString to get the query string values. I cant to Request.QueryString("userid") as in d URL userid will not be there.. So wat can i do for this ?


doof
Apr 17, 2009 12:43 AM
#

just encrypt the 3 params as a string

string myqrystring = crypto.encrypt(default.aspx?userid=1&username=a&location=b)

then pass it as www.mysite.com?myqrystring=xxxx

at the other end, decrypt, and iterate through each qry string named pair.


Jenna
Aug 19, 2009 2:46 PM
#

@kris

didn't u read the first parat...?


Joe
Dec 14, 2009 11:05 PM
#
Hi- Nice bit of code! Curious why you defined IV as a byte array but make key a string that you then used to create a byte array with Encoding.UTF8.GetBytes? Thanks for the help.

Pradeep
Dec 29, 2009 8:04 AM
#
not decrypting if the string length exceeeds 150

harjit singh
Jan 22, 2010 4:09 AM
#
Code is working fine but when we encrypt numbers, some the encrypted numbers contain '+' sign which I do'nt want to appear in querystring. Please suggest.

Thanks,
Bye.

shailesh
Feb 17, 2010 5:38 AM
#

Hi kevyan
nice solution but your download link is not working please correct it..


Abhishek Sur
Feb 17, 2010 2:40 PM
#
Hey, I already did similar kind of thing.

I used Rijndael to encrypt and then turned it to Base64 string and sent through query string.


Al
Mar 04, 2010 4:29 AM
#

Hi, I've been having a quick look at encryption and came across this site ... I've noticed that some of you are having trouble with the "+" symbol ... apparently the Request.QueryString object interprets the "+" symbol as a space. A Replace function on the decrypt string should solve it. (I've not actually used any encryption yet but thought this may help. Source:http://devcity.net/PrintArticle.aspx?ArticleID=47)


G3
Mar 19, 2010 5:40 AM
#
ur code is not as cute as u :P

Tauf
Apr 20, 2010 3:29 PM
#
I think has never worked on web based application...that is why he commenting like this..so please pray for him guys...so that he could get the chance to work and learn something important.. :)

tauf
Apr 20, 2010 3:31 PM
#
sorry i was talking about kris...

Slavi
Jun 07, 2010 11:55 AM
#
maybe you could try using Triple DES instead of just DES

Dilip Nikam
Sep 07, 2010 8:56 AM
#
Hi,

This is very nice article. But i am having one doubt.

If i am encrypt Querystring from serverside and i need querystring value into the javascreept then how can i do that ?

Castor troy
Sep 10, 2010 1:26 AM
#
G3 ...stop talking non-sense.....better learn smthn

Jonathan Wood
Dec 19, 2010 10:47 AM
#

Thanks for posting this. It's interesting to see how someone else approached this. You can see my approach at http://blackbeltcoder.com/Articles/asp/encrypting-query-arguments.


madhu
Jan 06, 2011 4:47 AM
#
Super... its works successfully

Sudha Madhuri
Jan 06, 2011 4:48 AM
#
Perfectly Working..
Thanks for the code.

Arunprasad
Mar 01, 2011 7:13 AM
#
Thanks it was very useful.

Easa
Mar 29, 2011 3:31 AM
#
Thank you it is useful for me

Shomaail
Apr 02, 2011 7:03 AM
#
decrypting a string sometimes gives empty string. I mean to say after about 7-8 trials one empty string is found!!. why is it that? Kindly fix it!

Rahul
Apr 19, 2011 6:36 AM
#
how to encrypt string with front end Flex 3 with back end Asp.Net.

Alex
May 12, 2011 6:32 PM
#
Looks like a lot of users are havving troube with the '+' when decrypting.. all use have to do is use the replace method and use some other character that is never generated.. hope this helps

w.w
Jun 10, 2011 3:08 AM
#
nice code.

thx a lot.

Azhar
Sep 21, 2011 2:30 AM
#
Great article....
so helpfull :)

pm
Sep 23, 2011 10:56 AM
#
I am getting a "invalid length for a base-64 char array".

I am using urlencode/urldecode before calling the methods to encrypt/decrypt.

I am getting this error when trying to decrypt in the following statement.

Byte[] byteArray = Convert.FromBase64String(text);

Any thoughts will be appreciated. Thank you in advance.

pm
Sep 23, 2011 11:10 AM
#
Sorry but I should add that there is and "!" within the text.

Atul kumar Prajapati
Dec 05, 2011 3:50 AM
#
I am getting this error when trying to decrypt in the following statement.

Byte[] byteArray = Convert.FromBase64String(text);

Renatas Daunys
Feb 07, 2012 1:24 AM
#
It is good practise encrypt also post parameters.

V
Jun 29, 2012 4:05 AM
#
Can I keep the stringkey dynamic and change it from client to client?

Garrett Raney
Dec 20, 2012 3:54 PM
#
Thanks!
Also, V, you can make stringkey dynamic by storing it in app settings and configure those based on each client. I use Visual Studio's configuration management to push specific config flies to the deployment folder.

hamarnath
Apr 24, 2013 9:04 AM
#
thank u very much great post

Leave a Comment