为了水博客不择手段(其实是ida自动绕反调试的插件没安上做不动NCTF了,呜呜呜)
tea已经水过了,那就水一篇rc4吧(
简介
RC4(来自Rivest Cipher 4的缩写)是一种流加密算法,密钥长度可变。它的加解密使用相同的密钥,因此也属于对称加密算法。RC4是有线等效加密(WEP)中采用的加密算法,也曾经是TLS可采用的算法之一。其最重要的实现是初始化算法和伪随机子密码的生成。
RC4的实现是以字节流的方式依次加密明文中的每一个字节,解密的时候也是依次对密文中的每个字节解密。(只有异或操作和S盒,所以加解密的过程相同,这是其可逆性的原理)
算法实现
先贴一份c++实现的代码
void init(char *s, char *key, int len)
{
char t[256] = {0};
char tmp = 0;
for (int i = 0; i < 256; ++i)
{
s[i] = i;
t[i] = key[i % len];
}
int j = 0;
for (int i = 0; i < 256; ++i)
{
j = (j + s[i] + t[i]) % 256;
swap(s[i], s[j]);
}
}
void crypt(char *s, char *data, int len)
{
int i = 0, j = 0, t = 0;
char tmp;
for (int k = 0; k < len; ++k)
{
i = (i + 1) % 256;
j = (j + s[i]) % 256;
swap(s[i], s[j]);
t = (s[i] + s[j]) % 256;
data[k] ^= s[t];
}
}
初始化算法(KSA)
先来看看初始化算法,此处我们假设S盒的长度是256,密钥key的长度为len(注意,RC4的密钥长度和密文长度/明文长度是相等的)且key的内容由用户规定,其长度的可变范围不限(超过256的不要就行)
void init(char *s, char *key, int len)
{
char t[256] = {0};
char tmp = 0;
for (int i = 0; i < 256; ++i)
{
s[i] = i;
t[i] = key[i % len];
}
int j = 0;
for (int i = 0; i < 256; ++i)
{
j = (j + s[i] + t[i]) % 256;
swap(s[i], s[j]);
}
}
初始化算法的步骤为:
- 初始化S盒为0-255
- 扩展密钥长度,具体操作是:若key的长度小于256,则不断将其复制进t盒,直到t盒长度刚好达到256(多的就不要了)
- 打乱S盒,使S盒近似为一个随机生成的、内含元素只有0-255的数组
在该算法中,i确保了s盒的每个元素都被处理过,而j确保了这种打乱的处理是近似于随机的