最近受西湖论剑的影响,又学了一个加解密算法RC4。这一题主要还是来自于一题MFC名叫junk的逆向题。这一题逆向到最后需要发现关键的加密算法是RC4,所以我就研究了一下。
这个算法还是比较简单的。主要的难度是在于产生密钥流。这个算法的原理就是让密钥流和明文进行异或然后放入密文中。这就是RC4的主要加密算法了。
那就重点来说说密钥流是怎么产生的吧.
首先获得RC4明文的长度,然后密钥流的长度是和明文的长度一致的。
- 首先初始化生成一个大小为255的s[i]的数组,里面存放的值为0到255。
. 初始化密钥,根据输入的密钥的长度,通过伪随机数生成相应得密钥。
. 生成一个大小为256的临时数组t[i]里面循环存放初始化之后的密钥。
. 根据密钥打乱初始化的S[];1
2
3
4
5
6
7
8int j =0;
for(int i=0;i<256;i++)
{
j=(j+s[i]+t[i])%256;
s[i]=s[j]^s[i]
s[j]=s[j]^s[i]
s[i]=s[j]^s[i]
} - 生成密钥流的关键。
1
2
3
4
5
6
7
8
9
10
11
12
13
14int i=0,j=0,t=0;
vector<char> k;
while(len--)
{
i=(i+1)%256;//保证s的数组不越界
j=(j+s[i])%256;//根据打乱之后的s[],来确定下一次j的值
s[i]=s[j]^s[i]//交换i和j的数组值,再一次打乱数组
s[j]=s[j]^s[i]
s[i]=s[j]^s[i]
t=(s[i]+s[j])%256;//根据i和j对应数组的值来确定最终的索引值
k.push_back(s[t]);//确定密钥流
} - 最后就是读取明文和密钥流进行异或,然后就产生了密文。
写完这RC4做个总结吧。
通过写完RC4,发现RC4就是一个对称加密算法,但是它不像base家族一样,将明文分组之后,然后再进行加密,这里的明文有多长,密钥流就有多长,可以一次加密完成。所以RC4属于对称加密算法中的序列密码。这样也使得RC4是
(1)、算法简洁易于软件实现,加密速度快,安全性比较高;
(2)、密钥长度可变,一般用256个字节。
最后的密钥流里面的值的范围为0-255。因为这个算法初始化之后,改变也只是根据索引值在相互交换,数组里面的值还是没有改变。这个算法变种的话可以从这里下手。
比如我初始化的时候,我不存放0-255的数。我可以逆序存放或者是直接存放随机值等等。思路很多,理解算法之后,想干啥就干啥。
最后贴上加密解密的源码:
不想研究怎么解密,我只想逆向的时候看得懂别人是什么加密算法就行。