*.RC4是一种流加密算法,用于数据的加解密。算法的核心是一种伪随机数生成器,被称为伪随机数字发生器(PRNG),它使用一个 256 字节的密钥来生成密钥流,加密和解密算法都是同一套算法。
相关代码如下:
/// <summary>
/// RC4流数据加解密
/// </summary>
public static class RC4Engine
{
#region Decrypt
/// <summary>
/// 解密
/// </summary>
/// <param name="key">密码</param>
/// <returns>返回解密字节数组</returns>
public static byte[] Decrypt(string key, byte[] data)
{
return ToRC4(key,data);
}
#endregion
#region Encrypt
/// <summary>
/// 加密
/// </summary>
/// <param name="key">密码</param>
/// <returns>返回加密字节数组</returns>
public static byte[] Encrypt(string key, byte[] data)
{
return ToRC4(key, data);
}
#endregion
#region ToRC4
/// <summary>
/// 将明文与伪随机数流进行异或运算,得到密文
/// </summary>
/// <param name="key">秘钥</param>
/// <param name="data">数据</param>
/// <returns>返回密文或明文</returns>
private static byte[] ToRC4(string key, byte[] data)
{
byte[] keys = Encoding.Unicode.GetBytes(key);
byte[] box = GetKeys(keys);
int x = 0;
int y = 0;
byte[] outData = new byte[data.Length];
for (int i = 0; i < data.Length; i++)
{
x = (x + 1) % 256;
y = (box[x] + y) % 256;
byte swapByte = box[x];
box[x] = box[y];
box[y] = swapByte;
outData[i] = (byte)(data[i] ^ box[(box[x] + box[y]) % 256]);
}
return outData;
}
#endregion
#region GetKeys
/// <summary>
/// 将秘钥散列成 256 字节
/// </summary>
/// <param name="keys">秘钥</param>
private static byte[] GetKeys(byte[] keys)
{
byte[] box = Enumerable.Range(0, 256).Select(i => (byte)i).ToArray();
for (int i = 0, j = 0; i < 256; i++)
{
j = (keys[i % keys.Length] + box[i] + j) % 256;
byte swapByte = box[i];
box[i] = box[j];
box[j] = swapByte;
}
return box;
}
#endregion
}
测试代码和结果如下:
static void Main(string[] args)
{
string RC4_KEY = "daniel123456^#*@reyv";
string text = "{abcdssdsadasdadasdsadasda123456}";
byte[] en_data = RC4Engine.Encrypt(RC4_KEY,Encoding.UTF8.GetBytes(text));
Console.WriteLine(en_data.Length);
Console.WriteLine(Encoding.UTF8.GetString(en_data));
byte[] de_data = RC4Engine.Decrypt(RC4_KEY, en_data);
var de_text = Encoding.UTF8.GetString(de_data);
Console.WriteLine(de_data.Length);
Console.WriteLine(de_text);
Console.ReadLine();
}