转换Mike Shaffer';s RC4对C#的加密

本文关键字:RC4 加密 Mike Shaffer 转换 | 更新日期: 2023-09-27 18:21:39

我正在关注一篇文章,https://web.archive.org/web/20210927195845/https://www.4guysfromrolla.com/articles/091802-1.3.aspx,它展示了如何将Mike Shaffer的VB RC4加密转换为C#,但我得到的结果与原始文章不同,https://web.archive.org/web/20210728063606/https://www.4guysfromrolla.com/webtech/010100-1.shtml.

使用来自原始文章的这个测试链接,https://web.archive.org/web/20210728061038/https://www.4guysfromrolla.com/demos/rc4test.htm,密码为"abc",纯文本为"testing123",我得到了"B9 F8 AA 5D 31 B1 8A 42 1E D4"。然而,当使用C#版本时,我得到了一些稍微不同的东西:"b9 f8 aa 5d 31 b1 160 42 1e d4"。我得到的是"160"而不是"8A"。

这是我的方法,它将ASCII(C#方法的最终结果)转换为十六进制:

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

这是我在文章中的C#代码(修改为静态类):

protected static int[] sbox = new int[256];
protected static int[] key = new int[256];
private static string password = "abc";
private static void RC4Initialize(string strPwd)
{
    int intLength = strPwd.Length;
    for (int a = 0; a <= 255; a++)
    {
        char ctmp = (strPwd.Substring((a % intLength), 1).ToCharArray()[0]);
        key[a] = Microsoft.VisualBasic.Strings.Asc(ctmp);
        sbox[a] = a;
    }

    int x = 0;
    for (int b = 0; b <= 255; b++)
    {
        x = (x + sbox[b] + key[b]) % 256;
        int tempSwap = sbox[b];
        sbox[b] = sbox[x];
        sbox[x] = tempSwap;
    }
}
private static string EnDeCrypt(string text)
{
    int i = 0;
    int j = 0;
    string cipher = "";
    RC4Initialize(password);

    for (int a = 1; a <= text.Length; a++)
    {
        int itmp = 0;
        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];
        char ctmp = text.Substring(a - 1, 1).ToCharArray()
        [0];
        itmp = Microsoft.VisualBasic.Strings.Asc(ctmp);
        int cipherby = itmp ^ k;
        cipher += Microsoft.VisualBasic.Strings.Chr(cipherby);
    }
    return cipher;
}

我这样调用这个方法:

public static string Encrypt(string text)
{ 
    return ConvertAsciiToHex(EnDeCrypt(text));
} 
RC4Encrypt.Encrypt("testing123");

我做错了什么?

转换Mike Shaffer';s RC4对C#的加密

这是对ChrChrW的调用之间的区别。

Chr将只取0到255之间的值,并将返回一个值超出该范围的字符(至少在我的机器上,如下所示)。你看到的是138。

128!=8364(?)130!=8218(,)131!=402(ƒ)132!=8222(,)133!=8230(.)134!=8224(+)135!=8225(╪)136!=710(^)137!=8240(%)138!=352(S)139!=8249()156!=339(o)158!=382(z)159!=376(Y)

为了更好地解释,可能需要VB.Net开发…;-)


然而,考虑到这一点,几乎不需要使用Microsoft.VisualBasic调用(调用VB时几乎不需要翻译…;-)),因为使用char对您正在做的事情来说效果很好。

itmp = ctmp;  //there's an implicit conversion for char to int
int cipherby = itmp ^ k;
Console.WriteLine("cipherby = {0}", cipherby);
cipher += (char)cipherby; //just cast cipherby to a char