Triple DES Encryption

BluJag

Perch
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" ?>
<configuration>

<!-- application specific settings -->
<appSettings>

<add key="ConnectionString" value="server=200.100.100.100;uid=myid;password=mypassword;database=mydatabase"/>
<add key="TimeOffset" value="5"/>


</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(DecryptedStream.Length - 1) 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.
 
Back
Top