RC4是一种对称加密算法,加密和加密使用同一个函数. 其中关于其历史这里也不多说了.
自己查一下百度百科.
RC4是很简单的一种加密算法, 主要就是分为两部分 RC4初始化 RC4加密
其实很简单.
初始化分为以下几个步骤
代码如下
typedef struct _RC4INFO
{
unsigned char s_box[256]; //定义一个自己使用的结构体
unsigned char t_box[256];
}RC4_INFO,*PRC4_INFO;
/*
初始化函数 需要传入key 以及 keylen
主要有几个步骤
1.初始化Sbox
2.将key填充到Tbox中
3.组合sbox[i] 与 tbox[i] 然后进行交换
*/
void rc4_init(PRC4_INFO prc4,unsigned char key[], unsigned int keylen)
{
int i = 0;
int j = 0;
unsigned char tmp;
if (prc4 == NULL)
{
return;
}
//初始化sbox与 Tbox
for (i = 0; i < 256; i++)
{
prc4->s_box[i] = i;
prc4->t_box[i] = key[i % keylen];
}
//交换sbox
for (i = 0; i < 256; i++)
{
//得出j下标
j = (j + prc4->s_box[i] + prc4->t_box[i]) % 256;
//开始交换
tmp = prc4->s_box[i];
prc4->s_box[i] = prc4->s_box[j];
prc4->s_box[j] = tmp;
}
}
RC4加密其实就是遍历数据,将数据与sbox进行异或加密,而在此之前还需要交换一次sbox的数据
交换完之后 再把s[i] + s[j]的组合当做下标再去异或.
代码如下.
void rc4_crypt(
unsigned char data[], //要加密的数据
unsigned int datalen, //要加密的数据长度
unsigned char key[], //加密数据所用的Key
unsigned int keylen) //加密数据所用的key长度
{
int dn = 0; //data[n]的意思
int i = 0;
int j = 0; // i j 分别用于交换sbox[i] 和 sbox[j]
int t = 0; //t = s[i] + s[j]
unsigned char tmp;
RC4_INFO rc4;
rc4_init(&rc4, key, keylen);
for (dn = 0; dn < datalen; dn++)
{
i = (i + 1) % 256;
j = (j + rc4.s_box[i]) % 256;
//swap
tmp = rc4.s_box[i];
rc4.s_box[i] = rc4.s_box[j];
rc4.s_box[j] = tmp; //上边这部分就是在交换s[i]与s[j]
//下边这部分就是得到T下标用于交换
t = (rc4.s_box[i] + rc4.s_box[j]) % 256;
data[dn] ^= rc4.s_box[t];
}
}
/* This file was generated by the Hex-Rays decompiler.
Copyright (c) 2007-2019 Hex-Rays <info@hex-rays.com>
Detected compiler: Visual C++
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <intrin.h>
typedef struct _RC4INFO
{
unsigned char s_box[256];
unsigned char t_box[256];
}RC4_INFO,*PRC4_INFO;
void rc4_init(PRC4_INFO prc4,unsigned char key[], unsigned int keylen)
{
int i = 0;
int j = 0;
unsigned char tmp;
if (prc4 == NULL)
{
return;
}
//init sbox an KeyBox(Tbox)
for (i = 0; i < 256; i++)
{
prc4->s_box[i] = i;
prc4->t_box[i] = key[i % keylen];
}
//swap sbox
for (i = 0; i < 256; i++)
{
j = (j + prc4->s_box[i] + prc4->t_box[i]) % 256;
tmp = prc4->s_box[i];
prc4->s_box[i] = prc4->s_box[j];
prc4->s_box[j] = tmp;
}
}
void rc4_crypt(
unsigned char data[], //要加密的数据
unsigned int datalen, //要加密的数据长度
unsigned char key[], //加密数据所用的Key
unsigned int keylen) //加密数据所用的key长度
{
int dn = 0; //data[n]的意思
int i = 0;
int j = 0; // i j 分别用于交换sbox[i] 和 sbox[j]
int t = 0; //t = s[i] + s[j]
unsigned char tmp;
RC4_INFO rc4;
rc4_init(&rc4, key, keylen);
for (dn = 0; dn < datalen; dn++)
{
i = (i + 1) % 256;
j = (j + rc4.s_box[i]) % 256;
//swap
tmp = rc4.s_box[i];
rc4.s_box[i] = rc4.s_box[j];
rc4.s_box[j] = tmp;
//得到T下标用于交换
t = (rc4.s_box[i] + rc4.s_box[j]) % 256;
data[dn] ^= rc4.s_box[t];
}
}
void EntryBuffer(unsigned char data[],unsigned int datalen)
{
unsigned char key[] = "pjrHeldsadf";
rc4_crypt(data, datalen, key, sizeof(key) / sizeof(key[0]));
}
int main()
{
char Hell[] = "Hello你好sdfsdaf";
EntryBuffer((unsigned char*)Hell,sizeof(Hell)/sizeof(Hell[0])); //加密
EntryBuffer((unsigned char*)Hell,sizeof(Hell)/sizeof(Hell[0])); //在调用一次就是解密了
return 0;
}
遇到上述特征可以认为是rc4
反汇编中有xmm0 下面进行调用了两个函数 sub_401040
观看数据区,看到这种大概率就是字符串,可以按A 或者R来进行转换看.
转换后看到就是我们的加密数据以及rc4的key(pjrheldsadf)
根据上述特征大概率就可以看出是rc4初始化函数. key填充到var_20C中. i填充到var_200中
再往下看就可以明显的看到数据异或了.很简单也可以自己写一个进行逆向.