Есть ли что-нибудь не так с этим кодом шифрования 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±:„Qp"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. расшифровать


Но это, кажется, не работает. Любые предложения о том, что может быть наверху что-то не так?
658   2  

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.

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

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

EDIT-некоторые ссылки на рабочий код RC4 в С#:

Comments

    Ничего не найдено.