5

C#でFoxycart XMLデータフィードを聴こうとしてい ますが、暗号化に帰着する問題が発生しています。

つまり、 RC4暗号化を使用して、エンコードおよび暗号化されたXMLとしてデータを送信します。

テストするために、C#でこれをテストするための(ユーザーが送信した)サンプルコードがいくつかあります。ユーザーの1人から提供されたこのサンプル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. 復号化

しかし、それは機能していないようです。上記で何が間違っている可能性があるかについての提案はありますか?

4

2 に答える 2

15

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.
于 2011-08-27T22:39:48.057 に答える
1

これは暗闇の中での撮影ですが...RC4を実装するクラスは、すべてがASCIIまたはCodePage 1252のいずれかであると想定しているように見えると確信しています。提供されるXMLはUTF-8と.NETであると想定しているため、どちらも間違っています。メモリ内の文字列表現はUTF16です。

私の仮定が正しければ、暗号化からデータを取り戻すときに、データはすでにスクランブルされています...

編集-C#で動作するRC4コードへのリンク:

于 2011-08-27T22:08:55.707 に答える