Imports System.IO
Imports System.Security.Cryptography

Public Class CryptoModule
    ' define the triple des provider
    Private m_des As New TripleDESCryptoServiceProvider

    ' define the local property arrays
    Private m_key() As Byte
    Private m_iv() As Byte = {8, 7, 6, 5, 1, 2, 3, 14}

    Public Function ByteArrayToHex(ByVal data As Byte()) As String
        Dim sb As New System.Text.StringBuilder(data.Length * 2)
        For Each val As Byte In data
            sb.Append(val.ToString("x2"))
        Next val
        Return sb.ToString
    End Function

    Public Function HexToByteArray(ByVal text As String) As Byte()
        Dim output(text.Length * 0.5 - 1) As Byte
        For i As Integer = 0 To output.Length - 1
            output(i) = Convert.ToByte(text.Substring(i * 2, 2), 16)
        Next i
        Return output
    End Function

    Public Function MassageKey(ByVal key As String) As Byte()
        Dim bHeader(3), bTrailer(3) As Byte 'create 4 random bytes before and after the 192-bit encryption key
        Dim rnd As New Random()

        rnd.NextBytes(bHeader)
        rnd.NextBytes(bTrailer)

        Dim bOldKey As Byte() = New System.Text.ASCIIEncoding().GetBytes(key)
        For i As Integer = 0 To bOldKey.Length - 1
            bOldKey(i) = bOldKey(i) + 10
        Next i

        Dim bNewKey(31) As Byte 'total massaged key length 32 bytes
        Array.Copy(bHeader, bNewKey, 4) 'put 4 bytes header before key
        Array.Copy(bOldKey, 0, bNewKey, 4, 24) '192-bit encryption key = 24 bytes
        Array.Copy(bTrailer, 0, bNewKey, 28, 4) 'put 4 bytes trailer after key

        Return bNewKey
    End Function

    Public Function UnMassageKey(ByVal key As Byte()) As String
        Dim bChoppedKey(23) As Byte
        Array.Copy(key, 4, bChoppedKey, 0, 24) 'skipping first 4 bytes random header, then get next 24 bytes as encryption key 
        For i As Integer = 0 To bChoppedKey.Length - 1
            bChoppedKey(i) = bChoppedKey(i) - 10
        Next i

        Return New System.Text.ASCIIEncoding().GetString(bChoppedKey)
    End Function

    Public Function UnMassageKeyString(ByVal key As String) As String
        Dim bOldKey As Byte() = New System.Text.ASCIIEncoding().GetBytes(key)
        Dim bChoppedKey(23) As Byte
        Array.Copy(bOldKey, 4, bChoppedKey, 0, 24) 'skipping first 4 bytes random header, then get next 24 bytes as encryption key 
        For i As Integer = 0 To bChoppedKey.Length - 1
            bChoppedKey(i) = bChoppedKey(i) - 10
        Next i

        Return New System.Text.ASCIIEncoding().GetString(bChoppedKey)
    End Function

    Public Function HashMessage(ByVal text As String) As Byte()
        Dim md5Hasher As New MD5CryptoServiceProvider
        Dim input() As Byte = New System.Text.UTF8Encoding().GetBytes(text)
        Return md5Hasher.ComputeHash(input)
    End Function

    Public Function CompareHash(ByVal input1() As Byte, ByVal input2() As Byte) As Boolean
        For i As Integer = 0 To input1.Length - 1
            If (input1(i) <> input2(i)) Then
                Return False
            End If
        Next i
        Return True
    End Function

    Public Function EncryptTripleDES(ByVal sKey As String, ByVal input() As Byte) As Byte()
        m_key = New System.Text.ASCIIEncoding().GetBytes(sKey)
        Return Transform(input, m_des.CreateEncryptor(m_key, m_iv))
    End Function

    Public Function DecryptTripleDES(ByVal sKey As String, ByVal input() As Byte) As Byte()
        m_key = New System.Text.ASCIIEncoding().GetBytes(sKey)
        Return Transform(input, m_des.CreateDecryptor(m_key, m_iv))
    End Function

    Public Function EncryptTripleDES(ByVal sKey As String, ByVal text As String) As String
        m_key = New System.Text.ASCIIEncoding().GetBytes(sKey)
        Dim input() As Byte = New System.Text.UTF8Encoding().GetBytes(text)
        Dim output() As Byte = Transform(input, m_des.CreateEncryptor(m_key, m_iv))
        Return ByteArrayToHex(output)
    End Function

    Public Function DecryptTripleDES(ByVal sKey As String, ByVal text As String) As String
        m_key = New System.Text.ASCIIEncoding().GetBytes(sKey)
        Dim input() As Byte = HexToByteArray(text)
        Dim output() As Byte = Transform(input, m_des.CreateDecryptor(m_key, m_iv))
        Return New System.Text.UTF8Encoding().GetString(output)
    End Function

    Private Function Transform(ByVal input() As Byte, ByVal CryptoTransform As ICryptoTransform) As Byte()
        ' create the necessary streams
        Using memStream As New MemoryStream
            Using cryptStream As 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))

                Transform = result
            End Using
        End Using
    End Function

    Public Function BuildSVSWebViewerQueryString(ByVal key As String, ByVal directory As String) As String
        Dim HashMsgInHex As String = ByteArrayToHex(HashMessage(directory))
        Return EncryptTripleDES(UnMassageKeyString(key), directory & "/" & HashMsgInHex)
    End Function
End Class