RC4加密算法学习笔记
原理
原理很简单,包括初始化算法(KSA)和伪随机子密码生成算法(PRGA)两大部分。
关键在于密钥流生成器的理解,个人认为该加密手段是通过生成密钥对256取模后得到下标的不确定性从而达到混乱和扩散的目的。
密钥生成
先放上一张原理图:
在初始化的过程中,密钥的主要功能是将S-box搅乱,i确保S-box的每个元素都得到处理,j保证S-box的搅乱是随机的。而不同的S-box在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列,将S-box和明文进行xor运算,得到密文,解密过程也完全相同。
/*初始化函数*/
void rc4_init(unsigned char*s,unsigned char*key, unsigned long Len)
{
int i=0,j=0;
unsigned char T[256]={0};
unsigned char tmp=0;
for(i=0;i<256;i++) {
s[i]=i;//s_box初始化为[0,255]
T[i]=key[i%Len];//key如果没到256位,就循环输入进T数组
}
for(i=0;i<256;i++) {
j=(j+s[i]+T[i])%256;//得到一个随机下标
swap(s[i],s[j]);//打乱s数组
}
}
加解密过程
加解密过程比较简单
/*加解密*/
void rc4_crypt(unsigned char*s,unsigned char*Data,unsigned long Len)
{//s为s_box,Data为明文,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;
swap(s[i],s[j]);//进一步打乱s_box
t=(s[i]+s[j])%256;//得到一个随机下标t,s[t]其实就是生成的密钥流中的一位
Data[k]^=s[t];//异或加密,那么解密过程就是再异或一次
}
}
调用过程
int main()
{
unsigned char s[256] = { 0 }, s2[256] = { 0 };//S-box
char key[256] = { "justfortest" };//我的理解是key不要有重复字节,否则s_box会不够乱
char pData[512] = "这是一个用来加密的数据Data";
unsigned long len = strlen(pData);
int i;
printf("pData=%s\n", pData);
printf("key=%s,length=%d\n\n", key, strlen(key));
rc4_init(s, (unsigned char*)key, strlen(key));//已经完成了初始化
printf("完成对S[i]的初始化,如下:\n\n");
for (i = 0; i<256; i++)
{
printf("%02X", s[i]);
if (i && (i + 1) % 16 == 0)putchar('\n');
}
printf("\n\n");
for (i = 0; i<256; i++)
//用s2[i]暂时保留经过初始化的s[i],因为加密函数会进一步对s_box进行置换
{
s2[i] = s[i];
}
printf("已经初始化,现在加密:\n\n");
rc4_crypt(s, (unsigned char*)pData, len);//加密
printf("pData=%s\n\n", pData);
printf("已经加密,现在解密:\n\n");
//rc4_init(s,(unsignedchar*)key,strlen(key));//初始化密钥
rc4_crypt(s2, (unsigned char*)pData, len);//解密
printf("pData=%s\n\n", pData);
return 0;
}
总的来说RC4并不难,也比较好看懂,解密脚本写起来也很方便,但是只要保证密钥不是若密钥,那么该算法具有很高的安全性,据分析128位的密钥已经足够安全,没有任何分析对该算法有效,因此可以放心使用。
参考文章:
RC4加密算法原理简单理解 - 沉默的赌徒 - 博客园 (cnblogs.com)