Search code examples
c#encryptionxor

c# Sagepay XOR encryption


I am trying to write the xor encryption in C# as sagepay encryption is only documented in VB.

the vb code is:

Public Shared Function simpleXor(ByVal strIn As String, ByVal strKey As String) As String
    Dim iInIndex As Integer
    Dim iKeyIndex As Integer
    Dim strReturn As String
    If Len(strIn) = 0 Or Len(strKey) = 0 Then
        simpleXor = ""
        Exit Function
    End If

    iInIndex = 1
    iKeyIndex = 1
    strReturn = ""

    '** Step through the plain text source XORing the character at each point with the next character in the key **
    '** Loop through the key characters as necessary **
    Do While iInIndex <= Len(strIn)
        strReturn = strReturn & Chr(Asc(Mid(strIn, iInIndex, 1)) Xor Asc(Mid(strKey, iKeyIndex, 1)))
        iInIndex = iInIndex + 1
        If iKeyIndex = Len(strKey) Then iKeyIndex = 0
        iKeyIndex = iKeyIndex + 1
    Loop

    simpleXor = strReturn
End Function

So far I have converted this to

        public static String SimpleXOR(String strIn, String strKey)
    {
        Int32 iInIndex, iKeyIndex;
        String strReturn;
        iInIndex = 1;
        iKeyIndex = 1;
        strReturn = "";

        while (iInIndex <= strIn.Length)
        {
            strReturn = strReturn & Strings.Chr(Strings.Asc(Strings.Mid(strIn, iInIndex, 1)) ^ Strings.Asc(Strings.Mid(strKey, iKeyIndex, 1)));
                iInIndex = iInIndex + 1;
            if (iKeyIndex == strKey.Length) iKeyIndex = 0;
            iKeyIndex = iKeyIndex + 1;

        }

    }

The problem is I didn't understand what this line is doing

strReturn = strReturn & Chr(Asc(Mid(strIn, iInIndex, 1)) Xor Asc(Mid(strKey, iKeyIndex, 1)))

so I ran it through a vb to c# converter and got the above. But it clearly is not valid c# code as far as I am aware.

Can anyone help?


Solution

  • There are two ways I can think of to do this:

    First, grab the current System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage of the thread, pass that into a new Encoding class instance using the GetEncoding method, then convert the strings to byte arrays using the Encoding instance's GetBytes method

        public static string SimpleXOR(string strIn, string strKey)
        {
            if (strIn.Length == 0 || strKey.Length == 0)
            {
                return string.Empty;
            }
    
            int inIndex = 0;
            int keyIndex = 0;
            string returnString = string.Empty;
    
            var currentCodePage = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ANSICodePage;
            var encoding = Encoding.GetEncoding(currentCodePage);
    
            var inString = encoding.GetBytes(strIn);
            var keyString = encoding.GetBytes(strKey);
    
            while (inIndex < inString.Length)
            {
                returnString += (char)(inString[inIndex] ^ keyString[keyIndex]);
    
                inIndex++;
    
                if (keyIndex == keyString.Length - 1)
                {
                    keyIndex = 0;
                }
                else
                {
                    keyIndex++;
                }
            }
    
            return returnString;
        }
    

    The other, simpler way would be to add a reference to Microsoft.VisualBasic in your C# project and let the converter generated code run. The Strings class will be avaliable, allowing you to just do Strings.Chr, Strings.Asc, and Strings.Mid.