0

Background: I'm trying to convert Mike Shaffer's VB RC4 encryption to C# (https://web.archive.org/web/20210927195845/https://www.4guysfromrolla.com/articles/091802-1.3.aspx). See a previous question of mine at Converting Mike Shaffer's RC4Encryption to C#.

It seems my encryption is not working.

Using the demo page at: https://web.archive.org/web/20000303125329/http://www.4guysfromrolla.com:80/demos/rc4test.asp, with password of "abc":

Plain text: og;|Q{Fe should result in

A2 FA E2 55 09 A4 AB 16

However, my code is generating the 5th char as 9, instead of 09:

A2 FA E2 55 9 A4 AB 16

Another example - Plain text: cl**z!Ss should result in

AE F1 F3 03 22 FE BE 00

However, my code is generating:

AE F1 F3 3 22 FE BE 0

It seems it's only a problem with certain non-alphanumeric characters.

Here's my code:

private static string EnDeCrypt(string text)
{
    int i = 0;
    int j = 0;
    string cipher = "";

    // Call our method to initialize the arrays used here.
    RC4Initialize(password);


    // Set up a for loop.  Again, we use the Length property
    // of our String instead of the Len() function
    for (int a = 1; a <= text.Length; a++)
    {
        // Initialize an integer variable we will use in this loop
        int itmp = 0;

        // Like the RC4Initialize method, we need to use the %
        // in place of Mod
        i = (i + 1) % 256;
        j = (j + sbox[i]) % 256;
        itmp = sbox[i];
        sbox[i] = sbox[j];
        sbox[j] = itmp;

        int k = sbox[(sbox[i] + sbox[j]) % 256];

        // Again, since the return type of String.Substring is a
        // string, we need to convert it to a char using
        // String.ToCharArray() and specifying that we want the
        // first value, [0].
        char ctmp = text.Substring(a - 1, 1).ToCharArray()
        [0];
        itmp = ctmp;  //there's an implicit conversion for char to int

        int cipherby = itmp ^ k;

        cipher += (char)cipherby; //just cast cipherby to a char 
    }

    // Return the value of cipher as the return value of our
    // method
    return cipher;
}

public static string ConvertAsciiToHex(string input)
{
    return string.Join(string.Empty, input.Select(c => Convert.ToInt32(c).ToString("X")).ToArray());
}

public static string Encrypt(string text)
{
    return ConvertAsciiToHex(EnDeCrypt(text));
}

Here's how I get my encrypted result:

var encryptedResult = RC4Encrypt.Encrypt(valuetoencrypt);

Community
  • 1
  • 1
Rivka
  • 2,172
  • 10
  • 45
  • 74
  • Why are you bothering with RC4, especially now that the news of it being crap have finally made it from cryptographers' blogs into mainstream tech media? Unless you're doing this as an exercise, I suggest you implement something different. –  Nov 20 '13 at 22:07
  • Because the system that I'm working with currently uses RC4 encryption (in asp... it all goes together), and until that is changed, this is the way it needs to be done. But 100% agreed. – Rivka Nov 20 '13 at 22:10
  • Ah, legacy strikes again. Doesn't .NET have an RC4 implementation built in, or at least in a popular third party library? –  Nov 20 '13 at 22:13
  • AFAIK not built in. 3rd party - possibly... haven't looked much, (although admittedly should have first). – Rivka Nov 20 '13 at 22:18

1 Answers1

1

The output is correct (leading zeros don't change the value), your code is simply not padding values that fit into a single hex digit (such as 9 or 3 or 0). Use .ToString("X2") instead of .ToString("X").