Introduction
Inspired by this article, I tried to port the code to VB.NET. However, VB.NET does not have any implementation of arithmetic or bit operations, so it is difficult to implement the code / decode function of TEA. Readers can refer to the detailed explanation of XTEA on Wikipedia. I also took the advice from the discussion board to send 8 bytes at a time rather than 2 bytes at a time for encoding. System.bitConverter
is used for conversion between UINT32
and String
.
Using the Code
The solution contains two projects. ALgoXTEA is written in C# to implement the basic code / decode function:
public static void code(uint [] v, uint [] k)
{
uint y = v[0]; uint z = v[1];
uint sum = 0;
uint delta=0x9E3779B9; uint n=32;
while(n-->0)
{
y += (z << 4 ^ z >> 5) + z ^ sum + k[sum & 3];
sum += delta;
z += (y << 4 ^ y >> 5) + y ^ sum + k[sum >> 11 & 3];
}
v[0]=y; v[1]=z;
}
In the VB project XTEACryptoVB, you need to add a reference to AlgoXTEA and then declare the function to code / decode with the same signatures as:
Public Declare Sub code Lib "algoXtea.dll" _
Alias "code" (ByRef v As UInt32(), ByVal k As UInt32())
Public Declare Sub decode Lib "algoXtea.dll" (ByRef v As UInt32(), _
ByVal k As UInt32())
The encryption algorithm is shown below. An instance of the algoXtea
class is created, and the code / decode function can be called. 8 bytes of data is sent each time, and the formatKey()
function ensures that the key is 16 bits in length:
Public Function encrypt(ByVal Data As String, ByVal key As String) As String
If Data.Length = 0 Then
Throw New ArgumentException("Data must be at least 1 characater in length.")
End If
Dim formattedKey() As UInt32 = FormatKey(key)
If Data.Length Mod 8 <> 0 Then
For i As Integer = 0 To (8 - Data.Length Mod 8) - 1
Data = Data + Chr(0)
Next i
End If
Dim dataBytes As ArrayList
dataBytes = New ArrayList(Data.Length)
dataBytes.AddRange(System.Text.ASCIIEncoding.ASCII.GetBytes(Data))
Dim cipher As String = String.Empty
Dim tempData(2) As UInt32
Dim fourBytes(4) As Byte
For i As Integer = 0 To Data.Length - 1 Step 8
For k As Integer = 0 To 3
fourBytes(k) = dataBytes(i + k)
Next k
tempData(0) = BitConverter.ToUInt32(fourBytes, 0)
For k As Integer = 0 To 3
fourBytes(k) = dataBytes(i + 4 + k)
Next k
tempData(1) = BitConverter.ToUInt32(fourBytes, 0)
Dim al As New AlgoXTEA.algo
al.code(tempData, formattedKey)
cipher = cipher + Util.ConvertUintToString(tempData(0))
cipher = cipher + Util.ConvertUintToString(tempData(1))
Next i
Return cipher
End Function
The helper class is in Util.vb, which contains the method to convert between String
and UINT32
:
Public Shared Function ConvertStringToUint(ByVal input As String) As UInt32
If input.Length <> 4 Then
Throw New Exception("String length must be 4 in order to be converted!")
End If
Dim byteArray(4) As Byte
Dim inputArray(4) As Char
Dim output As UInt32
inputArray = input.ToCharArray
For i As Integer = 0 To 3
byteArray(i) = Convert.ToByte(inputArray(i))
Next i
output = BitConverter.ToUInt32(byteArray, 0)
Return output
End Function
However, there is a problem with sending encrypted text as a string. If the encrypted character happens to be chr(0)
, which is a terminating character, it will not work. A solution is to send the hexadecimal representation of the decoded numbers instead of the string.
Update
The XTeaHex.zip file contains the implementation of converting the encoded unsigned integers to a hexadecimal string. Each byte is converted to a hex number and is represented as two characters (0-F) - this will avoid the problem of chr(0)
.