这有什么错在C#这RC4加密代码 [英] Is there anything wrong with this RC4 encryption code in C#

查看:466
本文介绍了这有什么错在C#这RC4加密代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想听听 Foxycart XML数据传送专线在C#和运行成归结为加密的问题。



总之,他们寄过来作为自己使用 RC4加密编码和加密的XML数据。



要测试,他们有一些(用户提交)的示例代码用C#测试。我试着使用由用户之一提供此示例RC4解密代码,但它似乎没有工作,他们的支持人员认为其打倒C#RC4算法。因为它们不是C#的专家,我想我会在这里提问。这里是在FoxyCart论坛

总之,这里是(试图)通过加密的XML文件,并将其张贴到一个URL(注意DataFeedKey是我存储为一个字符串模拟响应代码成员变量):

 公众的ActionResult TestDataFeed()
{
串transactionData =(新的StreamReader(@ D:\SampleFeed.xml))ReadToEnd的();
串encryptedTransactionData = RC4.Encrypt(DataFeedKey,transactionData,FALSE);
串encodedTransactionData = HttpUtility.UrlEncode(encryptedTransactionData,Encoding.GetEncoding(1252));
串POSTDATA =FoxyData =+ encodedTransactionData;
VAR REQ =(HttpWebRequest的)WebRequest.Create(HTTP://本地主机:3396 / FoxyCart / RecieveDataFeed);
req.Method =POST;
req.ContentType =应用/的X WWW的形式,进行了urlencoded
变种SW =新的StreamWriter(req.GetRequestStream(),Encoding.ASCII);
sw.Write(POSTDATA);
sw.Close();
HttpWebResponse RESP = NULL;

{
RESP =(HttpWebResponse)req.GetResponse();
串R =新的StreamReader(resp.GetResponseStream())为ReadToEnd()。
}
赶上(引发WebException前)
{
字符串ERR =新的StreamReader(ex.Response.GetResponseStream())为ReadToEnd()。
}
返回NULL;
}

和这里是接收响应的回调方法。

  [ValidateInput(假)] 
公众的ActionResult RecieveDataFeed(的FormCollection集合)
{
串unencodedFeed = HttpUtility。 UrlDecode(集[FoxyData],Encoding.GetEncoding(1252));
串的交易= RC4.Decrypt(DataFeedKey,unencodedFeed,FALSE);
返回内容(狡猾);
}



相反张贴整个RC4类内嵌在这个问题上,的这里是这个RC4类的代码的链接。



由于我张贴在这个问题的顶部上面的链接,问题是当我检查



的内部变量交易

  RecieveDataFeed()

方法,我应该有常规的XML回来,但相反,我看到这一点: ?

 电子xø'V'U·8êUŸí¥MïSÅJÖó5Cå7ã... ALTH&放大器; THOG·¶ÝÙ3<ÍÖ¡«úüF¿¿ ßìNμ>4|Äu÷¼Â;£-w¤ƒûÊyL¹®½èíYö½'é(μJŒ〜»»= 3.25 F的‡•=±UI]'E³«OPC【U ^yyéå-°N ...5ðWF$泽娜^ _ Xë'ï%OE-5A 
欧€jŠt`Â9œÇÞLU&放大器;¼〜ç2îžúo/¢¶5,º*öOqÝ - 'ó®šuf™A5G-OC®‰ÁéiÇúW®|ÝÚ•ž±:。 Q\pp
ôÔiÛ!\DEAX3]ƒ°E€Œ«DQE‡KY @àö`gpöŽ÷NU = {μÏßKQKüå(O%U-9}¬°£7yo ,«ÜëCÍ/ + ...†OEI<‰AÚmÇÙå©&放大器;©¡xÙkŒföX¯ÃX&放大器;×°S |kÜ6Ô°Üú\Ätóü-äUƆÈáÅ\E8,¤âÈ4Ž¾«ãΚ_S‰xJº• BM *乔>‰ÜW-[؆ÆJÐà$½...9½šž_ÙÜù/®öÁVhzŠ¥U(ñ£²6b6¢ëße¤oáIðZuK} AEU]T¼*åZêñß5K-½òQSåRNÇë'Å¡
A•yiÈX•bØðIk ¿WxwNàäx®<?CV + X™¥电子!gd4â¤nÔ<¢½ÐªÊQ!,。e8s
Gyª4¼ò,}Yœ,¹±è‡Jy进行} SAE
ƒ|ýK'Ð }〜B|E3!0°ú'A-5Þ³£9 $-8äÏ©?
œ‡8GÂø



代码看起来正确的:




  1. 加密

  2. 编码

  3. 解码

  4. 解密



但它似乎并不奏效。在什么可能是上述问题?任何建议


解决方案

我有点由CR4类的代码感到惊讶。我看不出它怎么会可靠地工作。



中的代码使用windows-1252编码编码字符编码成字节,然后加密字节,并试图字节解码成字符。这将不能可靠地工作,因为你只能解码来自编码字符字节。



该方法接受一个字符串并返回一个字符串,但它应该采取一个字节数组,并返回一个字节数组,类似于如何在框架中的所有加密类做它



下面是就像一个版本:

 公共类RC4 {

公共静态的byte []加密(字节[] PWD,字节[]数据){
INT A,I,J,K,TMP;
INT []键,盒;
字节[]密码;

键= INT新[256];
盒= INT新[256];
密码=新的字节[data.Length]

为(i = 0; I< 256;我++){
键[i] = PWD [我%pwd.Length]
盒[我] =我;
}
为(J = = 0; I< 256;我++){
J =(J +盒[I] +键[I])256%;
TMP =盒[我]
盒[i] =盒[J]。
盒[J] = tmp目录;
}
为(A = J = = 0; I< data.Length;我++){
A ++;
A(%)= 256;
J + =盒[A];
Ĵ%= 256;
TMP =盒[A];
盒[A] =盒[J]。
盒[J] = tmp目录;
K =盒[((盒[A] +盒[J])256%)];
密码[I] =(字节)(数据[I] ^ K);
}
返回密码;
}

公共静态的byte []解密(字节[] PWD,字节[]数据){
返回加密(PWD,数据);
}

}



例如:

 字符串数据=这是一个考验。 
字节[]键= {1,2,3,4,5};

//加密
字节[] = ENC RC4.Encrypt(键,Encoding.UTF8.GetBytes(数据));

//变成的Base64交通便利的表单数据
串的base64 = Convert.ToBase64String(ENC);

Console.WriteLine(BASE64);

//变回字节数组
的byte []代码= Convert.FromBase64String的(Base64);

//解密
串DEC = Encoding.UTF8.GetString(RC4.Decrypt(键,代码));

Console.WriteLine(DEC);



输出:

  5lEKdtBUswet4yYveWU2 
这是一个考验。


I am trying to listen to the Foxycart XML Datafeed in C# and running into an issue which boils down to encryption.

In short, they send over their data as encoded and encrypted XML using RC4 encryption.

To test, they have some (user submitted) sample code to test this with C#. I tried using this sample RC4 decryption code provided by one of the users but it doesn't seem to work and their support staff thinks its down with the C# RC4 algorithm. Since they are not C# experts, i figured i would ask here. Here is the post on the FoxyCart forum

Anyway, here is the code that (tries to) simulate the response by encrypting an XML file and posting it to a URL (NOTE that DataFeedKey is a string that i have stored as a member variable):

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;
}

and here is the callback method that receives the response.

[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");
}

Instead of posting the whole RC4 class inline in this question, here is a link to the code of this RC4 class.

As i posted in the above link at the top of the question, the issue is when i check the variable transaction inside the

 RecieveDataFeed()

method, i should have the regular XML back but instead i see this:

É?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Âø

The code looks right:

  1. Encrypt
  2. Encode
  3. Decode
  4. Decrypt

but it doesn't seem to be working. Any suggestions on what might be wrong above?

解决方案

I am a bit surprised by the code in the CR4 class. I can't see how it would work reliably.

The code uses windows-1252 encoding to encode characters into bytes, then it encrypts the bytes and tries to decode the bytes into characters. That won't work reliably, as you can only decode bytes that comes from encoding characters.

The method takes a string and returns a string, but it should take a byte array and return a byte array, similar to how all the encryption classes in the framework does it.

Here is a version that works like that:

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);
  }

}

Example:

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);

Output:

5lEKdtBUswet4yYveWU2
This is a test.

这篇关于这有什么错在C#这RC4加密代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆