C#中的RC4加密代码有什么问题吗

我试图在C#中听取Foxycart XML Datafeed并遇到一个归结为加密的问题。

简而言之,他们使用RC4加密将数据作为编码和加密的XML发送。

为了测试,他们有一些(用户提交的)示例代码来使用C#对其进行测试 。 我尝试使用其中一个用户提供的示例RC4解密代码,但它似乎不起作用,他们的支持人员认为它使用C#RC4算法。 由于他们不是C#专家,我想我会问这里。 这是FoxyCart论坛上的post

无论如何,这里的代码是(尝试)通过加密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·¶ÝÙ34¦Ä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. 解码

但它似乎没有起作用。 关于上面可能出错的任何建议?

我对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或CodePage 1252 – 两者都是错误的,因为我认为提供的XML是UTF-8和.NET内存中的字符串represantion是UTF16 …

如果我的假设是正确的,那么当您从加密中获取数据时,数据已经被加扰…

编辑 – 在C#中使用RC4代码的一些链接:

Interesting Posts