Making TripleDES Simple in Visual Basic .NET






4.60/5 (54 votes)
Jun 30, 2004
2 min read

470217
This is a simple wrapper class that provides an easy interface for encrypting and decrypting byte arrays and strings.
Introduction
There are many, many examples of how to do encryption and decryption in .NET. So why one more? Well, for one thing, I find that the majority of good code examples of any type are issued in C#. This isn't surprising, since those from a C++ or Java background will have an easier transition to C# than a similarly experienced Visual Basic developer moving to VB.NET. It will take time for the VB.NET community to develop into what the C++ and Java community already has at its disposal. So, I thought that a solid, simple VB.NET example would do well.
Overview
This code example does four things that I think are missing from the examples that I have seen so far:
- It's written in Visual Basic .NET. Not that it is in any way superior or inferior to C#, but most of the other examples (and all of the good ones) were done in C#.
- It uses the UTF-8 encoder to ensure that the strings which are encrypted or decrypted are in an 8-bit format. Many examples that I see use the ASCII encoding, which is a 7-bit format. When you combine this with TripleDES (which uses 3, 8-bit blocks for the key), you can get yourself into situations where you cannot decrypt something you encrypted.
- It uses the
Convert
object's Base-64 methods to make sure that the encrypted text is output in such a way that it can be easily stored in text files and/or database fields without the risk of your encrypted content being inadvertently modified by implicit conversions. - It centralizes the actual encryption and decryption functionality into a single method, thus eliminating what would otherwise be 99% redundant code.
The Code
The complete cTripleDES
class in VB.NET:
Imports System.IO
Imports System.Text
Imports System.Security.Cryptography
Friend Class cTripleDES
' define the triple des provider
Private m_des As New TripleDESCryptoServiceProvider
' define the string handler
Private m_utf8 As New UTF8Encoding
' define the local property arrays
Private m_key() As Byte
Private m_iv() As Byte
Public Sub New(ByVal key() As Byte, ByVal iv() As Byte)
Me.m_key = key
Me.m_iv = iv
End Sub
Public Function Encrypt(ByVal input() As Byte) As Byte()
Return Transform(input, m_des.CreateEncryptor(m_key, m_iv))
End Function
Public Function Decrypt(ByVal input() As Byte) As Byte()
Return Transform(input, m_des.CreateDecryptor(m_key, m_iv))
End Function
Public Function Encrypt(ByVal text As String) As String
Dim input() As Byte = m_utf8.GetBytes(text)
Dim output() As Byte = Transform(input, _
m_des.CreateEncryptor(m_key, m_iv))
Return Convert.ToBase64String(output)
End Function
Public Function Decrypt(ByVal text As String) As String
Dim input() As Byte = Convert.FromBase64String(text)
Dim output() As Byte = Transform(input, _
m_des.CreateDecryptor(m_key, m_iv))
Return m_utf8.GetString(output)
End Function
Private Function Transform(ByVal input() As Byte, _
ByVal CryptoTransform As ICryptoTransform) As Byte()
' create the necessary streams
Dim memStream As MemoryStream = New MemoryStream
Dim cryptStream As CryptoStream = New _
CryptoStream(memStream, CryptoTransform, _
CryptoStreamMode.Write)
' transform the bytes as requested
cryptStream.Write(input, 0, input.Length)
cryptStream.FlushFinalBlock()
' Read the memory stream and convert it back into byte array
memStream.Position = 0
Dim result(CType(memStream.Length - 1, System.Int32)) As Byte
memStream.Read(result, 0, CType(result.Length, System.Int32))
' close and release the streams
memStream.Close()
cryptStream.Close()
' hand back the encrypted buffer
Return result
End Function
End Class
The complete cTripleDES
class in C#:
using System;
using System.IO;
using System.Text;
using System.Security.Cryptography;
namespace Utilities.Crypto
{
class cTripleDES
{
// define the triple des provider
private TripleDESCryptoServiceProvider m_des =
new TripleDESCryptoServiceProvider();
// define the string handler
private UTF8Encoding m_utf8 = new UTF8Encoding();
// define the local property arrays
private byte[] m_key;
private byte[] m_iv;
public cTripleDES(byte[] key, byte[] iv)
{
this.m_key = key;
this.m_iv = iv;
}
public byte[] Encrypt(byte[] input)
{
return Transform(input,
m_des.CreateEncryptor(m_key, m_iv));
}
public byte[] Decrypt(byte[] input)
{
return Transform(input,
m_des.CreateDecryptor(m_key, m_iv));
}
public string Encrypt(string text)
{
byte[] input = m_utf8.GetBytes(text);
byte[] output = Transform(input,
m_des.CreateEncryptor(m_key, m_iv));
return Convert.ToBase64String(output);
}
public string Decrypt(string text)
{
byte[] input = Convert.FromBase64String(text);
byte[] output = Transform(input,
m_des.CreateDecryptor(m_key, m_iv));
return m_utf8.GetString(output);
}
private byte[] Transform(byte[] input,
ICryptoTransform CryptoTransform)
{
// create the necessary streams
MemoryStream memStream = new MemoryStream();
CryptoStream cryptStream = new CryptoStream(memStream,
CryptoTransform, CryptoStreamMode.Write);
// transform the bytes as requested
cryptStream.Write(input, 0, input.Length);
cryptStream.FlushFinalBlock();
// Read the memory stream and
// convert it back into byte array
memStream.Position = 0;
byte[] result = memStream.ToArray();
// close and release the streams
memStream.Close();
cryptStream.Close();
// hand back the encrypted buffer
return result;
}
}
}
Using the cTripleDES
class in VB.NET:
' define the local key and vector byte arrays
Private ReadOnly key() As Byte = _
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, _
15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
Private ReadOnly iv() As Byte = {8, 7, 6, 5, 4, 3, 2, 1}
' instantiate the class with the arrays
Private des As New cTripleDES(key, iv)
' for the example, define a variable with the encrypted value
Private ReadOnly encryptedData As String = "++XIiGymvbg="
' now, decrypt the data
Private decryptedData As String = des.Decrypt(encryptedData)
' the value of decryptedData should be "test",
' but for our example purposes, let's re-encrypt it
Private newEncryptedData As String = des.Encrypt(decryptedData)
Using the cTripleDES
class in C#:
// define the local key and vector byte arrays
byte[] key = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24};
byte[] iv = {8, 7, 6, 5, 4, 3, 2, 1};
// instantiate the class with the arrays
cTripleDES des = new cTripleDES(key, iv);
// for the example, define a variable with the encrypted value
string encryptedData = "++XIiGymvbg=";
// now, decrypt the data
string decryptedData = des.Decrypt(encryptedData);
// the value of decryptedData should be "test",
// but for our example purposes, let's re-encrypt it
string newEncryptedData = des.Encrypt(decryptedData);
Conclusion
Hopefully, this simple, straight-forward example shows how to effectively and efficiently wrap the TripleDES (or any other encryption) functionality in Visual Basic .NET syntax. Of course, the same principles can just as easily be applied to a C#, J#, or managed C++ implementation.
Update (March 17, 2005)
It's been nearly two years since I first published this article and it's gotten a fair number of views, votes, and thanks. I'd like to thank you all for your kindness and, in return, I have updated the article with the much asked-for C# version of the class. Happy coding!