Introduction
This is an enhancement and "mash" to several articles on encryption and changing passwords. The problem is that I needed something that is not only encrypted, but also easy to implement as well as something that expires.
Background
Several months ago, I implemented an application using the ASP.NET membership controls which are in Visual Studio 2005. Part of this implementation allows for password recovery. The problem that I was faced with is the password that goes back to the user is not only very strange but the whole process is a little cumbersome. After looking around on the Internet, I came across a way to reset the password based on pushing a link from an email. The problem with this approach is that if someone does not delete the email after using it or if someone can interpret the userid then the password could be reset without someone's permission or knowledge. That is why I created a small class that has solved these problems. In essence, it takes an encryption key along with the username and a time stamp and creates a URL with the encrypted key.
The decryption part takes the URL and using the encryption key verifies that the date and time stamp is still valid. If it is, then you can assume that this is the user within a period of a couple of minutes. I recommend setting the length to no more than 30 minutes, but it is configurable.
Inside this file, I have also attached a small sample application which shows how to implement this. Once you get the hang of it, you can use it for just about anything. If there is a better way or comments, then please let me know.
Using the Code
Download the code and open up the encryption class. It contains three properties and two public
functions.
The properties are:
//
Public Property UserName() As String
Get
Return m_username
End Get
Set(ByVal value As String)
m_username = value
End Set
End Property
Public Property EncryptionKey() As String
Get
Return m_EncryptionKey
End Get
Set(ByVal value As String)
m_EncryptionKey = value
End Set
End Property
Public Property ExpireDateTime() As DateTime
Get
Return m_ExpireDateTime
End Get
Set(ByVal value As DateTime)
m_ExpireDateTime = value
End Set
End Property
//
The two public
class are:
Public Function Encrypt() As String
If String.IsNullOrEmpty(m_EncryptionKey) Then
Throw New Exception("Encryption Key is Required")
End If
If String.IsNullOrEmpty(m_ExpireDateTime.ToString) Then
Throw New Exception("Expiration Date is Required")
End If
Dim buffer() As Byte = Encoding.ASCII.GetBytes(serialize())
Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
Dim MD5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
des.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(m_EncryptionKey))
des.IV = IV
Return Convert.ToBase64String(des.CreateEncryptor.TransformFinalBlock_
(buffer, 0, buffer.Length))
End Function
Public Function Decrypt(ByVal EncryptedUsername As String) As String
If String.IsNullOrEmpty(m_EncryptionKey) Then
Throw New Exception("Encryption Key is not set")
End If
Try
Dim buffer() As Byte = Convert.FromBase64String(EncryptedUsername)
Dim des As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider
Dim MD5 As MD5CryptoServiceProvider = New MD5CryptoServiceProvider
des.Key = MD5.ComputeHash(ASCIIEncoding.ASCII.GetBytes(m_EncryptionKey))
des.IV = IV
deserialize(Encoding.ASCII.GetString_
(des.CreateDecryptor.TransformFinalBlock(buffer, 0, buffer.Length)))
Return Encoding.ASCII.GetString(des.CreateDecryptor.TransformFinalBlock_
(buffer, 0, buffer.Length))
Catch ex As CryptographicException
Throw New Exception("Crypto error")
Catch ex As FormatException
Throw New Exception("FormatExpection")
End Try
End Function
Points of Interest
This code was taken from several different articles on this site and combined to create this class. These articles are as follows: Password Recovery and TamperProofQueryString along with some original code.
History
- 08.22.2007 - Version 1 (Initial upload)