Geeks With Blogs

News
Ivan Porto Carrero Placeholder.Add("Really Cool Stuff");

Someone I know told me I have to share more of my code and that I should blog more.

The first one I don't know because most of it is not yet as I want it to be. Once I feel good about what I wrote then I will. I will also try to stick to the things least explained in .net.

Today I want to talk about some strategies on protecting your query strings.  Again I will just post a class this time it is slightly documented ;-)
This class can be used to perform encryption of a string. 
The methods for this are EncryptText and DecryptText

She can also be used to perform encryption-fingerprinting of a querystring.
The methods for this are EncodeQs and GetQueryKeys.
you can also use DecodeQs but then you'll have to parse your string yourself again.

The last function of this class is to be used to secure fast expiring parameters ie. to keep your images or javascripts hidden from visitor.
The methods to use for this are CreateParams and Getparams to store and retrieve the variables from session state. And you pass the id on as an encrypted querystring using EncodeQs and GetQueryKeys to retrieve the id. With this id you can then get the values from session state.

Somewhere I in the code I replace a space with the + sign. I tried using htmlencode/decode an urlencode/decode but I believe they gave me funny reactions. It has been again a while since i wrote this class so I don't know completely anymore why I took this approach.

To get you started with encryption I found this link : http://www.codeproject.com/dotnet/SimpleEncryption.asp

 

   

    1 using System;

    2 using System.Collections;

    3 using System.Collections.Specialized;

    4 using System.Text;

    5 using System.Security.Cryptography;

    6 using System.IO;

    7 

    8 namespace Flanders.Library.WebControls.Resources

    9 {

   10     public sealed class SecureParams

   11     {

   12         const string c_EncryptionKey = "Your24Characterstring!!!";

   13         ///

   14         /// Encrypts the text using RijndaelManaged 256-bits encryption. Using the default key

   15         ///

   16         /// The text to encrypt.

   17         /// A base64 encoded string that represents the encrypted data

   18         public static string EncryptText(string strTxt)

   19         {

   20             return Encrypt(strTxt, c_EncryptionKey);

   21         }

   22 

   23         ///

   24         /// Decrypts the text that was encrypted using the encrypt method of this class.

   25         ///

   26         /// The base64 encrypted string.

   27         /// A decrypted string

   28         public static string DecryptText(string strTxt)

   29         {

   30             return Decrypt(strTxt, c_EncryptionKey);

   31         }

   32 

   33         ///

   34         /// Encrypts the text using RijndaelManaged 256-bits encryption. Using the provided encryption key

   35         ///

   36         /// The text to encrypt.

   37         /// The encryption key (24 characters).

   38         /// A base64 encoded string that represents the encrypted data

   39         public static string Encrypt(string strTxt, string encryptKey)

   40         {

   41             byte[] byKey = { };

   42             byte[] IV ={ 55, 103, 246, 79, 36, 99, 167, 3, 42, 5, 62, 83, 184, 7, 209, 13, 145, 23, 200, 58, 173, 10, 121, 222, 88, 09, 45, 67, 94, 12, 34, 5 };

   43             try

   44             {

   45                 byKey = Encoding.UTF8.GetBytes(encryptKey);

   46                 RijndaelManaged rm = new RijndaelManaged();

   47                 rm.BlockSize = 256;

   48                 rm.IV = IV;

   49                 rm.KeySize = 256;

   50                 rm.Key = new SHA256Managed().ComputeHash(byKey);

   51                 byte[] inputByteArray = Encoding.UTF8.GetBytes(strTxt);

   52                 MemoryStream ms = new MemoryStream();

   53                 CryptoStream cs = new CryptoStream(ms, rm.CreateEncryptor(), CryptoStreamMode.Write);

   54                 cs.Write(inputByteArray, 0, inputByteArray.Length);

   55                 cs.FlushFinalBlock();

   56                 return Convert.ToBase64String(ms.ToArray());

   57             }

   58             catch (Exception ex)

   59             {

   60                 return ex.Message;

   61             }

   62         }

   63 

   64         ///

   65         /// Decrypts the text using RijndaelManaged 256-bits encryption. Using the provided encryption key

   66         ///

   67         /// The base64 encrypted string.

   68         /// The encryption key (24 characters).

   69         /// A decrypted string

   70         public static string Decrypt(string strTxt, string decryptKey)

   71         {

   72             byte[] byKey = { };

   73             byte[] IV ={ 55, 103, 246, 79, 36, 99, 167, 3, 42, 5, 62, 83, 184, 7, 209, 13, 145, 23, 200, 58, 173, 10, 121, 222, 88, 09, 45, 67, 94, 12, 34, 5 };

   74             try

   75             {

   76                 byKey = Encoding.UTF8.GetBytes(decryptKey);

   77                 RijndaelManaged rm = new RijndaelManaged();

   78                 rm.BlockSize = 256;

   79                 rm.IV = IV;

   80                 rm.KeySize = 256;

   81                 rm.Key = new SHA256Managed().ComputeHash(byKey);

   82                 byte[] inputByteArray = Convert.FromBase64String(strTxt);

   83                 MemoryStream ms = new MemoryStream();

   84                 CryptoStream cs = new CryptoStream(ms, rm.CreateDecryptor(), CryptoStreamMode.Write);

   85                 cs.Write(inputByteArray, 0, inputByteArray.Length);

   86                 cs.FlushFinalBlock();

   87                 System.Text.Encoding encoding = System.Text.Encoding.UTF8;

   88                 return encoding.GetString(ms.ToArray());

   89             }

   90             catch (Exception ex)

   91             {

   92                 return ex.Message;

   93             }

   94         }

   95 

   96         ///

   97         /// Creates the params.  This method should be used when you need to pass variables ie. from a page to a handler.  It stores the encryption in

   98         /// in the session state.  This is the most secure option provided but can only be used with sessionstate for now.

   99         ///

  100         /// The key.

  101         /// The param.

  102         ///

  103         /// This will store the encrypted value of the querystring in a session object (it expires and dissapears together with the session).

  104         /// the sesionkey value should be passed (optionally as an encoded query string) as the querystring to the new page/handler.

  105         ///

  106         public static void CreateParams(string sessionkey, string param)

  107         {

  108             System.Web.HttpContext _context = System.Web.HttpContext.Current;

  109             _context.Session[sessionkey] = EncryptText(param);

  110         }

  111 

  112         ///

  113         /// Gets the params.  This method should be used to get the params as a hashtable form the encrypted querystring

  114         ///

  115         /// The param.

  116         /// A hashtable that contains the encrypted values from the querystring created with CreateParams

  117         public static Hashtable GetParams(string sessionkey)

  118         {

  119             System.Web.HttpContext _context = System.Web.HttpContext.Current;

  120             string var = DecryptText(_context.Session[sessionkey].ToString());

  121             Hashtable ht = new Hashtable();

  122             string[] vars = var.Split(Convert.ToChar("&"));

  123             foreach (string s in vars)

  124             {

  125                 ht.Add(s.Split(Convert.ToChar("="))[0], s.Split(Convert.ToChar("="))[1]);

  126             }

  127             return ht;

  128         }

  129 

  130         ///

  131         /// Gets the params.  This method should be used to get the params as a hashtable form the encrypted querystring

  132         ///

  133         /// The encrypted query string.

  134         ///

  135         /// A NameValueCollection that contains the decrypted values from the querystring

  136         ///

  137         public static NameValueCollection GetQueryKeys(string encryptedQueryString)

  138         {

  139             System.Web.HttpContext _context = System.Web.HttpContext.Current;

  140             string var = DecodeQs(encryptedQueryString);

  141             NameValueCollection ht = new NameValueCollection();

  142             string[] vars = var.Split(Convert.ToChar("&"));

  143             foreach (string s in vars)

  144             {

  145                 ht[s.Split(Convert.ToChar("="))[0]] = s.Split(Convert.ToChar("="))[1];               

  146             }

  147             return ht;

  148         }

  149 

  150         ///

  151         /// Gets the params.  This method should be used to get the params as a hashtable form the encrypted querystring

  152         ///

  153         /// The encrypted query string.

  154         /// The encryption key.

  155         ///

  156         /// A NameValueCollection that contains the decrypted values from the querystring

  157         ///

  158         public static NameValueCollection GetQueryKeys(string encryptedQueryString, string encryptionKey)

  159         {

  160             System.Web.HttpContext _context = System.Web.HttpContext.Current;

  161             string var = DecodeQs(encryptedQueryString,encryptionKey);

  162             NameValueCollection ht = new NameValueCollection();

  163             string[] vars = var.Split(Convert.ToChar("&"));

  164             foreach (string s in vars)

  165             {

  166                 ht[s.Split(Convert.ToChar("="))[0]] = s.Split(Convert.ToChar("="))[1];

  167             }

  168             return ht;

  169         }

  170 

  171         ///

  172         /// Encodes the querystring using a default key and the expiration timestamp is set to 90 years.

  173         ///

  174         /// The query string.

  175         ///

  176         public static string EncodeQs(string qs)

  177         {

  178             return EncodeQs(qs, c_EncryptionKey);

  179         }

  180 

  181         ///

  182         /// Encodes the querystring using a specified key and the expiration timestamp is set to 90 years.

  183         ///

  184         /// The query string.

  185         /// The encryption key.

  186         ///

  187         public static string EncodeQs(string qs, string key)

  188         {

  189             return EncodeQs(qs, key, DateTime.Now.AddYears(90));

  190         }

  191 

  192         ///

  193         /// Encodes the querystring using a specified key and the expiration timestamp is set to 90 years.

  194         ///

  195         /// The query string.

  196         /// The encryption key.

  197         ///

  198         public static string EncodeQs(string qs, DateTime expiration)

  199         {

  200             return EncodeQs(qs, c_EncryptionKey, DateTime.Now.AddYears(90));

  201         }

  202 

  203         ///

  204         /// Encodes the querystring using the specified key and the specified expiration date.

  205         ///

  206         /// The querystring.

  207         /// The encryptionkey.

  208         /// The expiration.

  209         ///

  210         public static string EncodeQs(string qs, string key, DateTime expiration)

  211         {

  212             System.Web.HttpContext _context = System.Web.HttpContext.Current;

  213             string encrypted = EncryptText(qs + "," + expiration.ToString());

  214             string query = encrypted + HashQuery(encrypted, key);

  215             return query;

  216         }

  217         ///

  218         /// Decodes the qs.

  219         ///

  220         /// The qs.

  221         ///

  222         public static string DecodeQs(string qs)

  223         {

  224             return DecodeQs(qs, c_EncryptionKey);

  225         }

  226 

  227         ///

  228         /// Decodes the qs.

  229         ///

  230         /// The query string.

  231         /// The encryption key (24 characters).

  232         ///

  233         public static string DecodeQs(string qs,string key)

  234         {

  235             qs = qs.Replace(" ", "+") ; //something doesn't handle spaces very well, so we replace them with a + sign

  236             string encrypted = qs.Split(Convert.ToChar("-"))[0];

  237             string hashVal = qs.Split(Convert.ToChar("-"))[1];

  238             if (ValidateHash(hashVal,encrypted, key ))

  239             {

  240                 string Qs = DecryptText(encrypted);

  241                 string[] vars = Qs.Split(Convert.ToChar(","));

  242                 string var = vars[0];

  243                 string date = vars[1];

  244                 DateTime tocheck = Convert.ToDateTime(date);

  245                 if (DateTime.Now > tocheck)

  246                     throw new QueryStringExpiredException("Url expired... "+ date + "  " +DateTime.Now.ToString());

  247                 return var;

  248             }

  249             else

  250                 throw new QueryStringInvalidHashException("Url has been messed with...");

  251         }

  252 

  253         private static string HashQuery(string value, string key)

  254         {

  255             System.Security.Cryptography.MACTripleDES mac3des = new System.Security.Cryptography.MACTripleDES();

  256             System.Security.Cryptography.MD5CryptoServiceProvider md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();

  257             mac3des.Key = md5.ComputeHash(Encoding.UTF8.GetBytes(key));

  258             return Convert.ToChar("-") + Convert.ToBase64String(mac3des.ComputeHash(Encoding.UTF8.GetBytes(value)));

  259         }

  260 

  261         private static bool ValidateHash(string value,string data, string key)

  262         {

  263             String calcHash = "";

  264             String storedHash = "";

  265             MACTripleDES mac3des = new MACTripleDES();

  266             MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();

  267             mac3des.Key = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(key));

  268             try

  269             {

  270                 storedHash = Encoding.UTF8.GetString(System.Convert.FromBase64String(value));

  271                 calcHash = Encoding.UTF8.GetString(mac3des.ComputeHash(Encoding.UTF8.GetBytes(data)));

  272                 if (storedHash != calcHash)

  273                 {

  274                     return false;

  275                 }

  276             }

  277             catch

  278             {

  279                 throw new QueryStringInvalidHashException("Invalid comparison hash for query string.");

  280             }

  281             return true;

  282         }

  283     }

  284 

  285     public class QueryStringExpiredException : Exception

  286     {

  287         public QueryStringExpiredException() : base() { }

  288         public QueryStringExpiredException(string message) : base(message) { }

  289         public QueryStringExpiredException(string message, Exception ex):base(message,ex){}

  290     }

  291 

  292     public class QueryStringInvalidHashException : Exception

  293     {

  294         public QueryStringInvalidHashException() : base() { }

  295         public QueryStringInvalidHashException(string message) : base(message) { }

  296         public QueryStringInvalidHashException(string message, Exception ex) : base(message, ex) { }

  297     }

  298 }

Posted on Monday, January 2, 2006 7:23 PM | Back to top

Copyright © Ivan Porto Carrero | Powered by: GeeksWithBlogs.net