Triple DES Encryption

Here are a couple of routines to encrypt / decrypt data using Triple DES. They were taken from the ASP.NET Developers Cookbook and altered to make them work properly.

You will need these lines at the top of your .vb file

Imports System
Imports System.Web
Imports System.Configuration
Imports System.Data
Imports System.Data.SqlClient
Imports System.Security.Cryptography

Namespace Helpers

Public Class Functions

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Function Encryptdata(ByVal ClearText As String) As Byte()

        Dim Password As String = "somesecretphrase"
	Note that you could pass your Password as a parameter, in which case the function would start like this

Public Function Encryptdata(ByVal ClearText As String,ByVal Password As String) As Byte()

        Dim KeySize As Integer = 24  '192 bit
        Dim Hash() As Byte
        Dim PasswordArray() As Byte = New [Byte](Password.Length) {}
        Dim tdeskey(KeySize - 1) As Byte
        Dim IV As Byte() = {1, 2, 3, 4, 5, 6, 7, 8}
        Dim Encoder As New System.Text.UTF8Encoding
        'Dim encoder As New System.Text.ASCIIEncoding
        Encoder.GetBytes(Password, 0, Password.Length, PasswordArray, 0)
        'hash the password into the key byte array
        Dim SHA As New System.Security.Cryptography.SHA1CryptoServiceProvider
        Hash = SHA.ComputeHash(PasswordArray)
        Dim i As Integer
        For i = 0 To KeySize - 1
            tdeskey(i) = Hash((i Mod Hash.Length))
        Next
        '***********************************************************************
        'encrypt the string data
        'create a service provider
        Dim tdes As New System.Security.Cryptography.TripleDESCryptoServiceProvider
        'create an ICryptTransform using the key and initialisation vector
        Dim cryptoTransform As System.Security.Cryptography.ICryptoTransform = tdes.CreateEncryptor(tdeskey, IV)
        'create an output stream ot hold the encrypted data
        Dim EncryptedStream As New System.IO.MemoryStream
        'create a crypto stream to perform the encryption
        Dim crStream As New System.Security.Cryptography.CryptoStream(EncryptedStream, cryptoTransform, CryptoStreamMode.Write)
        '***************************************************************************
        'Get the input string into the byte array
        Dim Input As Byte() = Encoder.GetBytes(Trim(ClearText))
        'write the input data to the output stream via the cryptoStream
        crStream.Write(Input, 0, Input.Length) 
        crStream.FlushFinalBlock()
        'reset the output stream to its beginning
        EncryptedStream.Position = 0
        Dim Output(EncryptedStream.Length) As Byte
        'read the stream back into a string
        EncryptedStream.Read(output, 0, CInt(EncryptedStream.Length))
        crStream.Close()
        EncryptedStream.Close()
        Encryptdata = Output
      
    End Function

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

To decrypt

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Function DecryptData(ByVal CypherText As Byte() ) As String

        Dim password As String = "somesecretphrase"   ' Note comment above about passing this as a parameter
        Dim KeySize As Integer = 24 '192 bit
        Dim hash() As Byte
        Dim passwordArray() As Byte = New [Byte](password.Length) {}
        Dim tdeskey(KeySize - 1) As Byte
        Dim IV As Byte() = {1, 2, 3, 4, 5, 6, 7, 8}
        Dim encoder As New System.Text.UTF8Encoding
        encoder.GetBytes(password, 0, password.Length, passwordArray, 0)
        'hash the password into the key byte array
        Dim SHA As New System.Security.Cryptography.SHA1CryptoServiceProvider
        hash = SHA.ComputeHash(passwordArray)
        Dim i As Integer
        For i = 0 To KeySize - 1
            tdeskey(i) = hash((i Mod hash.Length))
        Next
        '***********************************************************************
        'decrypt the string data
        'create a service provider
        Dim tdes As New System.Security.Cryptography.TripleDESCryptoServiceProvider
        'create an ICryptTransform using the key and initialisation vector
        Dim cryptoTransform As System.Security.Cryptography.ICryptoTransform = tdes.CreateDecryptor(tdeskey, IV)
        'create an output stream to hold the encrypted data
        Dim DecryptedStream As New System.IO.MemoryStream
        'create a CrytoStream to perform the decryption
        Dim crStream As New System.Security.Cryptography.CryptoStream(DecryptedStream, cryptoTransform, System.Security.Cryptography.CryptoStreamMode.Write)
        '***********************************************************************
        crStream.Write(CypherText, 0, CypherText.Length - 1)
         
        crStream.FlushFinalBlock()
        'reset the output stream to the beginning
        DecryptedStream.Position = 0
        'read the stream back into a string
        Dim output(DecryptedStream.Length) As Byte
        DecryptedStream.Read(output, 0, CInt(DecryptedStream.Length))
        crStream.Close()
        DecryptedStream.Close()

'For some reason which is beyond me the decrypted string has an extra character added to the end which causes mayhem with email programs and so forth, so the next few lines are essential

        Dim DeCryptText As String
        DeCryptText = Trim(encoder.GetString(output))
        DeCryptText = Left(DeCryptText, Len(DeCryptText) - 1)
      
        Return DeCryptText
   
    End Function

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Example of how to use these routines

Lets say you have a users email address and password stored in your database (if MS SQL use a varbinary datatype) which you encrypted. If the user forgets his password, a function like the one below will get it for him.

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Function Forgotten(ByVal Email As String) As Boolean
'1. Reminds person of forgotten password
Dim Password As String
Dim bR As Boolean
Dim Msg As String

        Dim myConnection As SqlConnection = New SqlConnection(ConfigurationSettings.AppSettings("ConnectionString"))
        'SP gets details of the member
        Dim myCommand As SqlCommand = New SqlCommand("Forgotten", myConnection)
        myCommand.CommandType = CommandType.StoredProcedure

        Dim parameterEmail As SqlParameter = New SqlParameter("@Email", SqlDbType.VarBinary, 100)
        parameterEmail.Value = Encryptdata(Email)
        myCommand.Parameters.Add(parameterEmail)

        Dim parameterPassword As SqlParameter = New SqlParameter("@Password", SqlDbType.VarBinary, 50)
        parameterPassword.Direction = ParameterDirection.Output
        myCommand.Parameters.Add(parameterPassword)

        myConnection.Open()
        Try
            myCommand.ExecuteNonQuery()
            Password = DecryptData(parameterPassword.Value)
            Forgotten = True
        Catch ex As Exception
            Password = ""
            Forgotten = False
        End Try
        myConnection.Close()

        If Password <> "" Then
            Msg = "Your password is " & Password
            bR = SendEmails("MyWebsite.com", Email, "Your Password", Msg) 'This is a simple generic email sending function
            If bR = True Then
                Forgotten = True
            Else
                Forgotten = False
            End If
        End If

    End Function

End Class
End Namespace
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The stored procedure for getting the password is

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CREATE PROCEDURE Forgotten

(
	@Email varbinary (100),
	@Password varbinary (50) OUTPUT
)

AS
SET NOCOUNT ON
SELECT @Password=Password FROM Logins WHERE Email=@Email

RETURN 

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

The ConfigurationSettings.AppSettings(“ConnectionString”)) bit comes from your web.config file. The IP address is a fake one - put in the IP address of your SQL Server on Jodohost

<?xml version="1.0" encoding="utf-8" ?>
<appSettings>
</appSettings>

<system.web>

etc etc etc

Encrypting sensitive data is a good idea and as you can see .net takes care of all the complicated bits for you. There is some good blurb about encryption at

http://www.rsasecurity.com/rsalabs/node.asp?id=2227

To fix your

For some reason which is beyond me the decrypted string has an extra character added to the end which causes mayhem with email programs and so forth, so the next few lines are essential

Change the following in the DecryptData Function

    'read the stream back into a string
    Dim output(DecryptedStream.Length) As Byte
    DecryptedStream.Read(output, 0, CInt(DecryptedStream.Length))
    crStream.Close()
    DecryptedStream.Close()

to

    'read the stream back into a string
    Dim output([B]DecryptedStream.Length - 1[/B]) As Byte
    DecryptedStream.Read(output, 0, CInt(DecryptedStream.Length))
    crStream.Close()
    DecryptedStream.Close()

Other than that Thanks for the code must appreciated - it was driving me nuts

Glad all is OK. I built a site ( https://offschool.net ) which uses Triple DES extensively, plus https, so it ought to be pretty secure. To set up the https part I just changed to a dedicated IP and hey presto that was it. However, you do get a security warning about the Certificate, but thats no real problem. To stop the warnings I think you have to buy a certificate from a Trusted Provider like Verisign or someone - but it costs a small fortune.