rc4
rc4算法经典地分为两大块 – s盒初始化&&加解密。
初始化算法实现
void rc4_init(unsigned char* s, unsigned char* key, unsigned long Len)
{
int i = 0, j = 0;
char k[256] = { 0 };
unsigned char tmp = 0;
for (i = 0; i < 256; i++)
{
s[i] = i;
k[i] = key[i % Len];
}
for (i = 0; i < 256; i++)
{
j = (j + s[i] + k[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换s[i]和s[j]
s[j] = tmp;
}
}
正常的s盒的初始状态是256位置0的,而后在算法中,通常是先为其置0~255的数值;而后进行s盒生成,根据密钥key的值与s盒的值生成交换位进行交换。这样进行256次以后生成了伪随机不可逆的s盒。
加解密算法实现
void rc4_crypt(unsigned char* s, unsigned char* Data, unsigned long Len)
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for (k = 0; k < Len; k++)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
tmp = s[i];
s[i] = s[j];//交换s[x]和s[y]
s[j] = tmp;
t = (s[i] + s[j]) % 256;
Data[k] ^= s[t];
}
}
rc4算法的加密和解密是一个算法,只不过一个是另一个的逻辑上的逆过程(异或)。rc4的加密算法的算法核心部分与我们输入的数据是无关的,其只受s盒的影响;而我们输入的数据只在单轮的最后被异或加密。
逆向情景假设
①只有密文
万事休矣
②有密文和密钥
密钥塞初始化里,走一遍流程就完事了
③有s盒和密文
s盒走一遍流程就完事了
④明文同时作为明文和密钥
万事休矣
总结:算法没魔改,走一遍流程就完事了
rc4算法可能的魔改的点
①初始化
可以魔改的点很多啊,s盒长度可以不为256,里面初始被赋值的数据可以不为0~255,交换的位数可以比如偷偷从
j = (j + s[i] + k[i]) % 256;
改成
j = (j + s[i] + k[i] * 2 + 1) % 256;
.② 加解密
最简单的可以在上述算法的i,j,t上动手脚。因为都做了一个mod256的操作嘛,所以感觉上里面瞎搞都没问题。
以及也可以在异或的时候动手脚,比如原来是
Data[k] ^= s[t];
我们可以将其改成
Data[k] ^= (s[t]+1);
rc4算法魔改逆向
因为rc4算法的核心思想在于其生成密钥盒的随机性,只要把s盒搞出来那其实就是随便解密。
而单纯的对rc4的算法进行魔改其实并不能提高多少难度。只要s盒还在或者密钥可知/可求,我们只需要使用这个被魔改过的算法,按照rc4传统的:初始化->解密流程执行一遍即可