Click here to Skip to main content
15,867,330 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hi Programmers,

I am facing a problem in my ASP.NET application after I implemented encryption in it. The QueryStringModule.cs file is used in my application.
The problem, which was not coming before I included that file in my project is when a user types a text in TextArea (HTML Control), the querystring gets the data in C# code behind from that text area as following:


in aspx page:
HTML
<textarea rows="5" cols="50" name="comments"></textarea>

And in code behind:
C#
 public string comments;
 new protected void Page_Load(object sender, EventArgs e)
{
   comments = Request.QueryString.Get("comments");
}


But, the error occurs only in Internet Explorer as the text value of that textbox after encryption increases and IE does not support the length of more than 2084 characters in URL.
The textbox is user friendly and has no limit of characters to input.
Is there any other way to encrypt the URL instead of the following code. I want to pass less data through querystring with encryption.
Please Help.

Here is the Encryption/Decryption Code which I am using in my Application:

C#
#region Using

using System;
using System.IO;
using System.Web;
using System.Text;
using System.Security.Cryptography;

#endregion

/// <summary>
/// Summary description for QueryStringModule
/// </summary>
public class QueryStringModule : IHttpModule
{

  #region IHttpModule Members

  public void Dispose()
  {
    // Nothing to dispose
  }

  public void Init(HttpApplication context)
  {
    context.BeginRequest += new EventHandler(context_BeginRequest);
  }

  #endregion

  private const string PARAMETER_NAME = "enc=";
  private const string ENCRYPTION_KEY = "key";

  void context_BeginRequest(object sender, EventArgs e)
  {
    HttpContext context = HttpContext.Current;
    if (context.Request.Url.OriginalString.Contains("aspx") && context.Request.RawUrl.Contains("?"))
    {
      string query = ExtractQuery(context.Request.RawUrl);
      string path = GetVirtualPath();

      if (query.StartsWith(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase))
      {
        //Decrypts the query string and rewrites the path.
        string rawQuery = query.Replace(PARAMETER_NAME, string.Empty);
        string decryptedQuery = Decrypt(rawQuery);
        context.RewritePath(path, string.Empty, decryptedQuery);
      }
      else if (context.Request.HttpMethod == "GET")
      {
        // Encrypt the query string and redirects to the encrypted URL.
        // Remove if you don't want all query strings to be encrypted automatically.
        string encryptedQuery = Encrypt(query);
        context.Response.Redirect(path + encryptedQuery);
      }
    }
  }

  /// <summary>
  /// Parses the current URL and extracts the virtual path without query string.
  /// </summary>
  /// <returns>The virtual path of the current URL.</returns>
  private static string GetVirtualPath()
  {
    string path = HttpContext.Current.Request.RawUrl;
    path = path.Substring(0, path.IndexOf("?"));
    path = path.Substring(path.LastIndexOf("/") + 1);
    return path;
  }

  /// <summary>
  /// Parses a URL and returns the query string.
  /// </summary>
  /// <param name="url">The URL to parse.</param>
  /// <returns>The query string without the question mark.</returns>
  private static string ExtractQuery(string url)
  {
    int index = url.IndexOf("?") + 1;
    return url.Substring(index);
  }

  #region Encryption/decryption

  /// <summary>
  /// The salt value used to strengthen the encryption.
  /// </summary>
  private readonly static byte[] SALT = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString());

  /// <summary>
  /// Encrypts any string using the Rijndael algorithm.
  /// </summary>
  /// <param name="inputText">The string to encrypt.</param>
  /// <returns>A Base64 encrypted string.</returns>
  public static string Encrypt(string inputText)
  {
    RijndaelManaged rijndaelCipher = new RijndaelManaged();
    byte[] plainText = Encoding.Unicode.GetBytes(inputText);
    PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(ENCRYPTION_KEY, SALT);

    using (ICryptoTransform encryptor = rijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16)))
    {
      using (MemoryStream memoryStream = new MemoryStream())
      {
        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
        {
          cryptoStream.Write(plainText, 0, plainText.Length);
          cryptoStream.FlushFinalBlock();
          return "?" + PARAMETER_NAME + Convert.ToBase64String(memoryStream.ToArray());
        }
      }
    }
  }

  /// <summary>
  /// Decrypts a previously encrypted string.
  /// </summary>
  /// <param name="inputText">The encrypted string to decrypt.</param>
  /// <returns>A decrypted string.</returns>
  public static string Decrypt(string inputText)
  {
    RijndaelManaged rijndaelCipher = new RijndaelManaged();
    byte[] encryptedData = Convert.FromBase64String(inputText);
    PasswordDeriveBytes secretKey = new PasswordDeriveBytes(ENCRYPTION_KEY, SALT);

    using (ICryptoTransform decryptor = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16)))
    {
      using (MemoryStream memoryStream = new MemoryStream(encryptedData))
      {
        using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
        {
          byte[] plainText = new byte[encryptedData.Length];
          int decryptedCount = cryptoStream.Read(plainText, 0, plainText.Length);
          return Encoding.Unicode.GetString(plainText, 0, decryptedCount);
        }
      }
    }
  }

  #endregion

}
Posted
Updated 6-Mar-21 23:30pm

1 solution

HTTP standard has no limit on URL length (http://www.faqs.org/rfcs/rfc2616.html[^] - section 3.2.1), not most of modern browsers...
However IE does limit it - http://support.microsoft.com/kb/q208427[^].
Here some numbers about URL length in different applications - http://www.boutell.com/newfaq/misc/urllength.html[^].

So you can't overcome it in case of IE and in some cases (very large text) other browsers may also fail...

---

OT. If your code not only a code-for-learning I hardly can see what it good for. What problem you try to solve with that HTTP module?
You may have to rethink your solution...
 
Share this answer
 
Comments
AR547 11-Feb-14 3:39am    
Instead of this, is there any way to store the value of that textbox in a session through javascript on textchange or onkeyup() method like this. And then how will I retrieve that session value in code behind if I cannot get the value through Request.QueryString?
Kornfeld Eliyahu Peter 11-Feb-14 3:50am    
First - use asp classes and not pure html tags - learn about it!!!
That will solve you the problem of passing values from client to server - you will not have to use awkward techniques, like query-string and session.
sankaran_kmm 23-Nov-14 23:51pm    
the above encryption and decryption working fine in IIS 7.0 Server ,but client side not working for encryption. we are using IE 7.0 Explorer.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900