Encrypting strings in .Net
Using query strings to pass values between pages is a very common practice in .Net, and many times you don't want users to be able to change the query string value to see another record. This can pose some problems especially if the data is in any way sensitive. So the one of the easiest ways to do this is to just encrypt the values and decrypt them when you need it.There are many articles out there to do this and I guess I am just kinda adding to an article found here. But I think add my own two cents and version of the code found on his site. I cleaned it up a little bit for my preferences and moved one or two things around.
First instead of having the functions pass in the symmetric key each time the function is called. I added a value in my web.config file that holds the key. This eliminates any sort of keying error and makes it easy to change if you want to for some reason.
<add key="EncryptionKey" value="!#$a8?2^" />The only real other change other than moving stuff outside the try/catch block that didn't need to be in there was to add this line:
stringToDecrypt = stringToDecrypt.Replace(" ", "+")The above article mentions that since we are adding the encrypted value to the query string browsers interpret a + as a space. So we have to replace it back the way it was before decrypting the string. The article relies on the caller function to handle that. I moved it inside my decrypt function so I don't have to remember to do it each time.
Here is my updated class. One thing to note is that I made them shared functions so I don't have to instantiate the class in order to use it.
Imports System
Imports System.IO
Imports System.Xml
Imports System.Text
Imports System.Configuration
Imports System.Security.Cryptography
Public NotInheritable Class Encryption
Public Shared Function Decrypt(ByVal stringToDecrypt As String) As String
Dim inputByteArray(stringToDecrypt.Length) As Byte
Dim key() As Byte = {}
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Dim encryptionKey As String = ConfigurationManager.AppSettings("EncryptionKey")
Dim des As New DESCryptoServiceProvider()
Dim ms As New MemoryStream()
Dim cs As CryptoStream
Try
stringToDecrypt = stringToDecrypt.Replace(" ", "+")
key = System.Text.Encoding.UTF8.GetBytes(Left(encryptionKey, 8))
inputByteArray = Convert.FromBase64String(stringToDecrypt)
cs = New CryptoStream(ms, des.CreateDecryptor(key, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
Return encoding.GetString(ms.ToArray())
Catch ex As Exception
Throw New Exception(ex.Message)
End Try
End Function
Public Shared Function Encrypt(ByVal stringToEncrypt As String) As String
Dim key() As Byte = {}
Dim IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Dim encryptionKey As String = ConfigurationManager.AppSettings("EncryptionKey")
Dim des As New DESCryptoServiceProvider()
Dim ms As New MemoryStream()
Dim inputByteArray() As Byte
Dim cs As CryptoStream
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(encryptionKey, 8))
inputByteArray = Encoding.UTF8.GetBytes(stringToEncrypt)
cs = New CryptoStream(ms, des.CreateEncryptor(key, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Return Convert.ToBase64String(ms.ToArray())
Catch e As Exception
Return e.Message
End Try
End Function
End Class
Labels: .NET
posted by Tom Becker at
5/23/2008
![]()

2 Comments:
Good points, man, and some good code too. Have you considered salting your hash and key values though? I like to salt with some consistent, but variable, piece of data to make the decryption key a bit more difficult to guess. In most cases, the easiest thing to use is the server time at pageload as a string (include seconds). Of course, you would need some place to temporarily hold this salting value between page loads so you can use it to recreate your key, but that's easy enough to do. At any rate, the idea is to make the key a bit more variable to make brute forcing it more difficult.
May 27, 2008 2:24 PM
You have a good point about the code being susceptible to a brute force attack. If you wanted to, you could store a unique key in session. The only thing you would have to keep in mind is that the session key name would also have to be unique.
For example, you have a list of customers, and to view the details for each customer you want a new window to open per customer(not the best example but bear with me), you would have to make sure you are using the correct symmetric key for each customer to decrypt the string correctly. So you could end up with many keys stored in your session state.
You can definitely do it, but it would require a few extra checks before you decrypt.
May 27, 2008 2:47 PM
Post a Comment
<< Home