使用 RC4/Hex 将解密功能从 Coldfusion 转换为 .NET



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

decrypt(theString,encryptKey,algorithmType,encodeType)

算法类型为 RC4,编码类型为十六进制。 无论出于何种原因,我在让它在 .net 中工作时遇到了很多麻烦。 是否有任何资源可用于这种事情,或者是否有一个相当简单的答案?

更新:

我首先使用此处的 RC4 类:C# 中的 RC4 加密。尽管我已将编码更改为 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;
}
}

更新:

如果"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 函数,您需要了解它们如何解码参数:

  • Encrypt(text, key , "RC4", "hex") - 将text视为 UTF-8 编码字符串,key视为 base64 编码字符串。

  • 解密(加密文本, 密钥, "RC4", "十六进制") - 将text视为十六进制编码字符串,key视为 base64 编码字符串。

您需要修改 C# 类才能执行相同的操作。

  1. 首先创建将字节 [] 转换为十六进制并将十六进制转换为字节 [] 的帮助程序函数:

    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,将加密文本解码为 十六进制。最后,将解密的值作为 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)));
    }
    

通过这些小的更改,C# 代码将生成与 CF 函数相同的结果。

注意:我建议阅读RC4的已知问题,并考虑切换到更安全的算法,如AES。

最新更新