使用RC4 / Hex将Decrypt函数从Coldfusion转换为.NET

时间:2017-03-24 21:20:00

标签: .net encryption coldfusion

我有一个ColdFusion页面,可以解密来自其他应用程序的一些数据。 ColdFusion代码非常简单:

decrypt(theString,encryptKey,algorithmType,encodeType)

算法类型为RC4,编码类型为十六进制。无论出于何种原因,我在使用.net时遇到了很多麻烦。有没有可用于此类事情的资源,还是有一个相当简单的答案?

更新

我已经开始使用此处找到的RC4课程:RC4 Encryption in C#。虽然我已将编码更改为Ascii,但结果仍然不匹配。

public static class RC4
{
   public static string Encrypt(string key, string data)
   {
      Encoding unicode = Encoding.Unicode;

      return Convert.ToBase64String(Encrypt(unicode.GetBytes(key), unicode.GetBytes(data)));
   }

   public static string Decrypt(string key, string data)
   {
      Encoding unicode = Encoding.Unicode;

      return unicode.GetString(Encrypt(unicode.GetBytes(key), Convert.FromBase64String(data)));
   }

   public static byte[] Encrypt(byte[] key, byte[] data)
   {
      return EncryptOutput(key, data).ToArray();
   }

   public static byte[] Decrypt(byte[] key, byte[] data)
   {
      return EncryptOutput(key, data).ToArray();
   }

   private static byte[] EncryptInitalize(byte[] key)
   {
      byte[] s = Enumerable.Range(0, 256)
        .Select(i => (byte)i)
        .ToArray();

      for (int i = 0, j = 0; i < 256; i++)
      {
         j = (j + key[i % key.Length] + s[i]) & 255;

         Swap(s, i, j);
      }

      return s;
   }

   private static IEnumerable<byte> EncryptOutput(byte[] key, IEnumerable<byte> data)
   {
      byte[] s = EncryptInitalize(key);

      int i = 0;
      int j = 0;

      return data.Select((b) =>
      {
         i = (i + 1) & 255;
         j = (j + s[i]) & 255;

         Swap(s, i, j);

         return (byte)(b ^ s[(s[i] + s[j]) & 255]);
      });
   }

   private static void Swap(byte[] s, int i, int j)
   {
      byte c = s[i];

      s[i] = s[j];
      s[j] = c;
   }
}

1 个答案:

答案 0 :(得分:0)

<强>更新

如果“encodeType”实际上是base64(非十六进制),那么它甚至更简单。修改Encrypt()函数将结果编码为base64。然后更改Decrypt()函数以解码来自 base64的值

public static string Encrypt(string base64Key, string plainText)
{

    return Convert.ToBase64String(Encrypt(Convert.FromBase64String(base64Key), Encoding.UTF8.GetBytes(plainText)));
}

public static string Decrypt(string base64Key, string base64Encrypted)
{
    return Encoding.UTF8.GetString(Encrypt(Convert.FromBase64String(base64Key), Convert.FromBase64String(base64Encrypted)));
}
  

我已将编码更改为Ascii。

关闭,但仍然无法正确解码输入。所以该类最终会尝试加密/解密错误的二进制文件,导致它失败。要完全复制CF函数,您需要了解它们如何解码参数:

你需要修改C#类来做同样的事情。

  1. 首先创建convert a byte[] to hexconvert hex to a byte[]

    的辅助函数
    public static string ByteArrayToHex(byte[] ba)
    {
        string hex = BitConverter.ToString(ba);
        return hex.Replace("-", "");
    }
    
    public static byte[] HexToByteArray(string hex)
    {
        return Enumerable.Range(0, hex.Length)
                         .Where(x => x % 2 == 0)
                         .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                         .ToArray();
    }
    
  2. 修改Decrypt()函数,将密钥解码为base64,将加密文本解码为hex。最后,将解密后的值作为UTF-8字符串返回。

    public static string Decrypt(string base64Key, string hexValue)
    {
        return Encoding.UTF8.GetString(Encrypt(Convert.FromBase64String(base64Key), HexToByteArray(hexValue)));
    }
    
  3. 修改加密功能,将密钥解码为base64,将纯文本解码为UTF-8。然后将加密值返回为十六进制。

    public static string Encrypt(string base64Key, string plainText)
    {
    
        return ByteArrayToHex(Encrypt(Convert.FromBase64String(base64Key), Encoding.UTF8.GetBytes(plainText)));
    }
    
  4. 通过这些小改动,C#代码将产生与CF函数相同的结果。

    注意:我建议您阅读known issues with RC4并考虑转换为更安全的算法,例如AES。