Что-то не так с этим кодом шифрования RC4 на C #?

Я пытаюсь послушать Foxycart XML Datafeed на C # и столкнулся с проблемой, которая сводится к шифрованию.

Короче говоря, они отправляют свои данные как закодированные и зашифрованные XML с использованием шифрования RC4.

Для тестирования у них есть некоторый (отправленный пользователем) образец кода, чтобы проверить это с помощью C #. Я попытался использовать этот образец кода расшифровки RC4, предоставленный одним из пользователей, но он, похоже, не работает, и их сотрудники службы поддержки думают, что это не так с алгоритмом C # RC4. Поскольку они не являются экспертами по C #, я подумал, что спрошу здесь. Вот сообщение на форуме FoxyCart

В любом случае, вот код, который (пытается) имитировать ответ, зашифровав XML-файл и отправив его по URL-адресу (ЗАМЕТЬТЕ, что DataFeedKey - это строка, которую я сохранил как переменную-член):

public ActionResult TestDataFeed()
{
    string transactionData = (new StreamReader(@"D:\SampleFeed.xml")).ReadToEnd();
    string encryptedTransactionData = RC4.Encrypt(DataFeedKey, transactionData, false);
    string encodedTransactionData = HttpUtility.UrlEncode(encryptedTransactionData,     Encoding.GetEncoding(1252));
    string postData = "FoxyData=" + encodedTransactionData;
    var req = (HttpWebRequest)WebRequest.Create("http://localhost:3396/FoxyCart/RecieveDataFeed");
    req.Method = "POST";
    req.ContentType = "application/x-www-form-urlencoded";
    var sw = new StreamWriter(req.GetRequestStream(), Encoding.ASCII);
    sw.Write(postData);
    sw.Close();
    HttpWebResponse resp = null;
    try
    {
        resp = (HttpWebResponse)req.GetResponse();
        string r = new StreamReader(resp.GetResponseStream()).ReadToEnd();
    }
    catch (WebException ex)
    {
        string err = new StreamReader(ex.Response.GetResponseStream()).ReadToEnd();
    }
    return null;
}

и вот метод обратного вызова, который получает ответ.

[ValidateInput(false)]
public ActionResult RecieveDataFeed(FormCollection collection)
{
    string unencodedFeed = HttpUtility.UrlDecode(collection["FoxyData"],     Encoding.GetEncoding(1252));
    string transaction = RC4.Decrypt(DataFeedKey, unencodedFeed, false);
    return Content("foxy");
}

Вместо того, чтобы размещать в этом вопросе весь класс RC4, вот ссылка на код этого класса RC4.

Как я писал в приведенной выше ссылке в верхней части вопроса, проблема заключается в том, когда я проверяю транзакцию переменной внутри

 RecieveDataFeed()

у меня должен быть обычный XML, но вместо этого я вижу следующее:

É?xø´ v´“Û·8êUŸí¥MïSÅJÖó5Cå7ã…ÄlÞ&þòG·¶ÝÙ3<ÍÖ¡«úüF¿¿ßìNµ>4¦Äu÷¼Â;£-w¤ƒûÊyL¹®½èíYö½’é(µJŒ~»»=3¼]F‡•=±Ùí]'鳫"øPç{Ù^yyéå–°ñ…5ðWF$zÉnÄ^_”Xë’ï%œ-5á
ÒÛ€jŠt`Â9œÇÞLU&¼~ç2îžúo/¢¶5,º*öOqÝ—‘.ó®šuf™å5G—õC®‰ÁéiÇúW®¦ÝÚ•Z±:„Q\p"p
ôÔiÛ!\D"ÉÂX3]ƒ°è€Œ«DQE‡kÝ@àö`gpöŽ÷nÛ={µÏßKQKüå(ö%¯¯Ü–9}¨¬°£7yo,«”ÜëCÍ/+…†ÕËî‘‹‰AÚmÇÙå©&©¡xÙkŒföX¯ÃX&×°S|kÜ6Ô°Üú\Ätóü-äUƆÈáÅ\ ’E8‚¤âÈ4Ž¾«ãΚ_Sï£y‰xJº•bm*jo›‰ÜW–[ô†ÆJÐà$½…9½šžˆ_ÙÜù/®öÁVhzŠ¥ú(ñ£²6ˆb6¢ëße¤oáIðZuK}ÆÙ]"T¼*åZêñß5K—½òQSåRN Çë'Å¡
ÕyiÈX •bØðIk¿WxwNàäx®‹?cv+X™¥E!gd4â¤nÔ‹¢½Ð”ªÊ­Q!‚.e8s
Gyª4¼ò,}Yœ‚¹”±E‡Jy}Sæ
ƒ¦ýK'Ð}~B¦E3!0°ú´A–5Þ³£9$–8äÏ©?
 œ‡8GÂø

Код выглядит правильно:

  1. Зашифровать
  2. Кодировать
  3. Декодировать
  4. Расшифровать

но похоже, что это не работает. Есть предложения по поводу того, что может быть не так?


person leora    schedule 27.08.2011    source источник


Ответы (2)


Меня немного удивил код в классе CR4. Я не вижу, как это будет работать надежно.

Код использует кодировку windows-1252 для кодирования символов в байты, затем он шифрует байты и пытается декодировать байты в символы. Это не будет работать надежно, поскольку вы можете декодировать только байты, полученные из символов кодировки.

Метод принимает строку и возвращает строку, но он должен принимать массив байтов и возвращать массив байтов, аналогично тому, как это делают все классы шифрования в структуре.

Вот версия, которая так работает:

public class RC4 {

  public static byte[] Encrypt(byte[] pwd, byte[] data) {
    int a, i, j, k, tmp;
    int[] key, box;
    byte[] cipher;

    key = new int[256];
    box = new int[256];
    cipher = new byte[data.Length];

    for (i = 0; i < 256; i++) {
      key[i] = pwd[i % pwd.Length];
      box[i] = i;
    }
    for (j = i = 0; i < 256; i++) {
      j = (j + box[i] + key[i]) % 256;
      tmp = box[i];
      box[i] = box[j];
      box[j] = tmp;
    }
    for (a = j = i = 0; i < data.Length; i++) {
      a++;
      a %= 256;
      j += box[a];
      j %= 256;
      tmp = box[a];
      box[a] = box[j];
      box[j] = tmp;
      k = box[((box[a] + box[j]) % 256)];
      cipher[i] = (byte)(data[i] ^ k);
    }
    return cipher;
  }

  public static byte[] Decrypt(byte[] pwd, byte[] data) {
    return Encrypt(pwd, data);
  }

}

Пример:

string data = "This is a test.";
byte[] key = { 1, 2, 3, 4, 5 };

// encrypt
byte[] enc = RC4.Encrypt(key, Encoding.UTF8.GetBytes(data));

// turn into base64 for convenient transport as form data
string base64 = Convert.ToBase64String(enc);

Console.WriteLine(base64);

// turn back into byte array
byte[] code = Convert.FromBase64String(base64);

// decrypt
string dec = Encoding.UTF8.GetString(RC4.Decrypt(key, code));

Console.WriteLine(dec);

Выход:

5lEKdtBUswet4yYveWU2
This is a test.
person Guffa    schedule 27.08.2011
comment
Это отлично работает, спасибо. Имею ли я лицензию на использование этого кода в коммерческом проекте? - person wezten; 31.03.2019
comment
@wezten: Да, вы можете использовать его как хотите. - person Guffa; 18.04.2019

Хотя это больше похоже на съемку в темноте ... Я почти уверен, что класс, реализующий RC4, выглядит так, будто он предполагает, что все это либо ASCII, либо CodePage 1252 - оба неверны, потому что я предполагаю, что предоставленный XML - это UTF-8 и .NET. преобразование строки в память - UTF16 ...

Если мое предположение верно, данные уже зашифрованы, когда вы получаете их из шифрования ...

РЕДАКТИРОВАТЬ - несколько ссылок на рабочий код RC4 на C #:

person Yahia    schedule 27.08.2011
comment
Но декодирование UTF-8 как ASCII не должно приводить к беспорядку в вопросе. - person svick; 28.08.2011
comment
это не только процесс en / декодирования, но и проверка связи с классом RC4 OP ... само шифрование сильно нарушает кодирование ... - person Yahia; 28.08.2011