我有一个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# 类才能执行相同的操作。
首先创建将字节 [] 转换为十六进制并将十六进制转换为字节 [] 的帮助程序函数:
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(); }
修改 Decrypt() 函数,将密钥解码为 base64,将加密文本解码为 十六进制。最后,将解密的值作为 UTF-8 字符串返回。
public static string Decrypt(string base64Key, string hexValue) { return Encoding.UTF8.GetString(Encrypt(Convert.FromBase64String(base64Key), HexToByteArray(hexValue))); }
修改加密函数,将密钥解码为 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。