2

I am updating code from VB6 to C#. I have a requirement of backwards compatibility. So files encrypted in the VB6 version need to be able to be decrypted in the C# version. So far I am unable to decrypt the files from the VB6 version.

The VB6 decrypt code is

Public Function DecryptFile(File() As Byte) As Byte()
    Dim op1 As Integer
    Dim i As Double
    Dim j As Integer
    Dim k As Integer
    Dim l As Integer
    Dim M As Double
    Dim r As Integer
    Dim The_Password As String
    pwork = Swap(Expand_Process("Password"))
    l = Len(Trim(pwork))
    M = UBound(File)
    k = 1
    For i = 0 To M
        j = File(i) - Asc(Mid(pwork, k, 1))
        If j < 0 Then
            j = j + 256
        End If
        File(i) = j
        k = k + 1
        If k > l Then
           k = 1
        End If
    Next i
    DecryptFile = File
End Function

Public Function Swap(The_Data As String)
    Dim Y, x As Integer
    Dim rest As String
    Dim r As Integer
    Dim wrk As String
    rest = ""
    x = Len(The_Data) / 2
    For Y = 1 To x
      wrk = Mid(The_Data, Y * 2, 1) & Mid(The_Data, Y * 2 - 1, 1)
      rest = rest & wrk
    Next Y
    Y = Len(The_Data) - (x * 2)
    If Y > 0 Then
       rest = rest & Right(The_Data, Y)
    End If
    Swap = rest
End Function

Public Function Expand_Process(The_Data As String) As String
    Dim p1 As Double
    Dim p2 As Integer
    Dim rd() As Variant
    Dim m1 As Integer
    Dim m2 As Integer
    Dim dwork As String
    rd = Array(7, 3, 5, 1, 4, 2)
    p1 = Round(Len("Password") / 5, 0)
    dwork = ""
    For p2 = 1 To 5
        m1 = rd(p2) * p1
        m2 = m1 - (p1 - 1)
        dwork = dwork & Mid(The_Data, m1, p1)
    Next p2
    Expand_Process = dwork
End Function

The C# code I've translated it to is

public byte[] Decrypt(byte[] file)
{
    int op1;
    int i;
    int j;
    int k;
    int l;
    double m;
    int r;
    string pword = Swap(Expand_Process("Password"));
    l = pword.Trim().Length;
    m = file.GetUpperBound(0);
    k = 1;
    for (i = 0; i <= m; i++)
    {
        string mid = Microsoft.VisualBasic.Strings.Mid(pword, k, 1);
        int asc = Microsoft.VisualBasic.Strings.Asc(mid);
        j = file[i] - asc;
        if (j < 0)
        {
            j += 256;
        }
        file[i] = Convert.ToByte(j);
        k++;
        if (k > l)
        {
            k = 1;
        }
    }
    return file;
}

private string Expand_Process(string data)
{
    double p1;
    int[] rd;
    double m1;
    double m2;
    rd = [7, 3, 5, 1, 4, 2];
    p1 = Math.Round((double)("Password".Length / 5), 0);
    string dwork = "";
    for (int p2 = 1; p2 <= 5; p2++)
    {
        m1 = rd[p2] * p1;
        m2 = m1 - (p1 - 1);
        dwork += dwork + Microsoft.VisualBasic.Strings.Mid(data, (int)m1, (int)p1);
    }
    return dwork;
}

private string Swap(string data)
{
    int x;
    int y;
    string rest;
    int r;
    string wrk;
    rest = "";
    x = data.Length / 2;
    for (y = 1; y <= x; y++)
    {
        wrk = Microsoft.VisualBasic.Strings.Mid(data, y * 2, 1) + Microsoft.VisualBasic.Strings.Mid(data, y * 2 - 1, 1);
        rest += wrk;
    }
    y = data.Length - (x * 2);
    if (y > 0)
    {
        rest += Microsoft.VisualBasic.Strings.Right(data, y);
    }
    return rest;
}

I am assuming the issue lies in the difference in typing between the two languages. For example, the line File(i) = j in VB6 cannot be written directly into C# as file[i] = j due to the file array being bytes. I tried using Convert.ToByte(j), but I'm not sure if this is an accurate translation.

If you could help me out identifying the issues with my translated code such that I can decrypt files that were encrypted with the old VB6 code, I would appreciate it. Thank you!

5
  • 2
    You may consider starting by identifying the proper data types. VB6 data types and Integral numeric types (C# reference). I also wouldn't attempt to convert the code, but rather re-write it in C# such that it gives the desired result. Commented Mar 2, 2024 at 20:21
  • 1
    What is the size of an integer? I would step through code on both old and new at same time and compare results. Make sure you are using ReadAllBytes method learn.microsoft.com/en-us/dotnet/api/… Commented Mar 2, 2024 at 20:29
  • 1
    @jdweng You will learn the sizes of the integers if you click the links in the comment posted 10 minutes before yours. Commented Mar 2, 2024 at 20:31
  • @GSerg : I know the answer. Vb6 is 16 bits while c# is 32 bits. Commented Mar 2, 2024 at 20:35
  • @jdweng I am using ReadAllBytes, thank you. I realize I missed that part of the code in my question. I am actually trying to decrypt a bitmap; and the decrypt method does complete "successfully". If I try to read the image from the decrypted byte array, I get an ArugmentException from Image.FromStream. Commented Mar 2, 2024 at 21:16

1 Answer 1

-1

Here is my translation

       static byte[] DecryptFile(byte[] File)
        {
            byte j;
            int k;
            int l;
            double M;
            int r;

            string pwork = Swap("Password");

            l = pwork.Trim().Length;
            k = 1;
            for(int i = 0; i < File.Length; i++)
            {
                byte chr = (byte)(pwork.Substring(k, 1).First());
                j = (byte)(File[i] - chr);
                File[i] = j;
                k = k + 1;
                if (k > l) k = 1;
            }
            return File;
        }
        static string Swap(string The_Data)
        {
            int x;
            string rest = "";
            int r;
            char wrk;

            x = The_Data.Length / 2;
            for (int Y = 1; Y <= x; Y++)
            {
                wrk = (char)(The_Data[Y * 2] & The_Data[Y * 2 - 1]);
                rest += wrk;

                Y = The_Data.Length - (x * 2);
                if (Y > 0) rest = rest + The_Data.Substring(The_Data.Length - Y);
            }
            return rest;
         }
Sign up to request clarification or add additional context in comments.

1 Comment

The problem is, in VB6 strings are 1-based while in c# they are 0-based. See an example. VB6 code is doing k = 1 and then Mid(pword, k, 1) so I guess you need to pass k-1 as first argument when calling c# Substring() method.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.