Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Tamper Proof Query String

0.00/5 (No votes)
22 Feb 2005 1  
Shows how to prevent/detect that string data was changed.

Sample screenshot

Introduction

Have you ever wanted to allow a user to bookmark a page, but you didn't want the user to be able to manually alter the query string parameters that would be required to generate the page?

These two functions take String Data and a Key and create a protected string which, if altered will generate an error when attempting to de-protect it. It also makes it nearly impossible for the user to validate data string with out knowing the Key.

This does not encrypt the data, an experienced individual can easily decode the data. However it is encoded with "base 64 encoding" so it is not human readable. You can however encrypt data using a separate function and then pass the encrypted data to these functions to protect it from tampering.

Real world example

One possible use is to save complex SQL selection criteria. It would just confuse the user if you passed this data on the querystring and it would be very important that they couldn't alter it and send it back. This is the type of thing you might generate from an advanced search form. Passing the data on the query string allows the user to bookmark the page or save the link for future use and yet does not allow them to submit data that is not generated by your web page.

Using the code

Pass your string data and secret key to TamperProofStringEncode. This generates a protected string which can be stored in a database, file, etc.

If you want to send this data on the querystring then you also need to use HttpUtility.UrlEncode. This formats the string so that it is read properly when using Request.QueryString.

Example Usage

<A href='yourpage.aspx?Data=
<%= HttpUtility.UrlEncode(TamperProofStringEncode("Your String Data Here", 
           "Your Secret Key")) %>'>Click Here</A>

This code evaluates to something like:

<a href='yourpage.aspx?Data=
         WW91ciBTdHJpbmcgRGF0YSBIZXJl-M%2b6N4pjf280%3d'>Click Here</a>

To read the data from the query string:

Try
  DataString = TamperProofStringDecode(Request.QueryString("Data"), _ 
          "Your Secret Key")
Catch ex As Exception
  'Invalid Data in query string

  'or data parameter not supplied

End Try

Details

    'Function to encode the string

    Function TamperProofStringEncode(ByVal value As String, _
                           ByVal key As String) As String
        Dim mac3des As New System.Security.Cryptography.MACTripleDES()
        Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider()
        mac3des.Key = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(key))
        Return Convert.ToBase64String( _
          System.Text.Encoding.UTF8.GetBytes(value)) & "-"c & _
          Convert.ToBase64String(mac3des.ComputeHash( _
          System.Text.Encoding.UTF8.GetBytes(value)))
    End Function

    'Function to decode the string

    'Throws an exception if the data is corrupt

    Function TamperProofStringDecode(ByVal value As String, _
              ByVal key As String) As String
        Dim dataValue As String = ""
        Dim calcHash As String = ""
        Dim storedHash As String = ""

        Dim mac3des As New System.Security.Cryptography.MACTripleDES()
        Dim md5 As New System.Security.Cryptography.MD5CryptoServiceProvider()
        mac3des.Key = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(key))

        Try
            dataValue = System.Text.Encoding.UTF8.GetString( _
                    Convert.FromBase64String(value.Split("-"c)(0)))
            storedHash = System.Text.Encoding.UTF8.GetString(_ 
                    Convert.FromBase64String(value.Split("-"c)(1)))
            calcHash = System.Text.Encoding.UTF8.GetString( _
              mac3des.ComputeHash(System.Text.Encoding.UTF8.GetBytes(dataValue)))

            If storedHash <> calcHash Then
                'Data was corrupted


                Throw New ArgumentException("Hash value does not match")
                'This error is immediately caught below

            End If
        Catch ex As Exception
            Throw New ArgumentException("Invalid TamperProofString")
        End Try

        Return dataValue

    End Function

Helper Functions

Optionally you can create two simple helper functions. The following are the two functions and their usage.

Private TamperProofKey As String = 
        ConfigurationSettings.AppSettings("TamperProofKey")
'or ... TamperProofKey As String = "YourUglyHardCodedKeyLike-alksfjlkasjfl3425"


Function QueryStringEncode(ByVal value As String) As String
  Return HttpUtility.UrlEncode(TamperProofStringEncode(value, TamperProofKey))
End Function

Function QueryStringDecode(ByVal value As String) As String
  Return TamperProofStringDecode(value, TamperProofKey)
End Function 
<A href='yourpage.aspx?Data=<%= 
       QueryStringEncode("Your Data String") %>'>HyperLink Text</A>

DataString = QueryStringDecode(Request.QueryString("Data")) 

Notes

I strongly recommend storing the key in the web.config file or at the very least in a private string variable. This prevents a typo in your code from resulting in transmitting the secret key to the client.

Please see the attached source code for more information on how to use these functions.

This function does not protect an empty string. An empty string results in the same protected value regardless of the key. Therefore if you want to allow an empty string then add a character to your data and then strip this character off when you retrieve the data. This modification could easily be added to these functions, but it makes the code more difficult to understand.

Additional Information

The ZIP file contains a working example as a single aspx page. Please try it out. The ZIP file also contains a C# class based implementation.

History

  • Replaced Chr(0) with "-"c to make the output string more portable. It can now be safely written to a plain text file or other basic text storage location.
  • Added a C# version class based implementation to the ZIP file.. This has currently only been tested on ASP.NET 2.0 beta 1.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here