前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RC4加密原理,代码解析,逆向小技巧.

RC4加密原理,代码解析,逆向小技巧.

作者头像
IBinary
发布2020-11-26 12:11:37
1.7K0
发布2020-11-26 12:11:37
举报
文章被收录于专栏:逆向技术逆向技术

RC4加密原理

一丶RC4

1.1 rc4介绍

​ RC4是一种对称加密算法,加密和加密使用同一个函数. 其中关于其历史这里也不多说了.

自己查一下百度百科.

1.2 RC4原理以及代码介绍

RC4是很简单的一种加密算法, 主要就是分为两部分 RC4初始化 RC4加密

其实很简单.

1.2.1rc4初始化介绍

初始化分为以下几个步骤

  • 初始化存储0-255字节的Sbox(其实就是一个数组)
  • 填充key到256个字节数组中称为Tbox(你输入的key不满256个字节则初始化到256个字节)
  • 交换s[i]与s[j] i 从0开始一直到255下标结束. j是 s[i]与T[i]组合得出的下标

代码如下

代码语言:javascript
复制
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;
    }
}
1.2.2 RC4加密

RC4加密其实就是遍历数据,将数据与sbox进行异或加密,而在此之前还需要交换一次sbox的数据

交换完之后 再把s[i] + s[j]的组合当做下标再去异或.

代码如下.

代码语言:javascript
复制
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];
    }
}
1.2.3完整代码
代码语言:javascript
复制
/* 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的逆向小技巧

3.1 逆向特征

  • 首先根据原理我们可以看到会初始化一个256字节的数组
  • 其次会将一个key也填充到数组中
  • 函数的话大概率都是两个参数,一个是key 一个是keylen

遇到上述特征可以认为是rc4

反汇编中有xmm0 下面进行调用了两个函数 sub_401040

观看数据区,看到这种大概率就是字符串,可以按A 或者R来进行转换看.

转换后看到就是我们的加密数据以及rc4的key(pjrheldsadf)

根据上述特征大概率就可以看出是rc4初始化函数. key填充到var_20C中. i填充到var_200中

再往下看就可以明显的看到数据异或了.很简单也可以自己写一个进行逆向.

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-11-23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • RC4加密原理
    • 一丶RC4
      • 1.1 rc4介绍
      • 1.2 RC4原理以及代码介绍
    • 三丶RC4的逆向小技巧
      • 3.1 逆向特征
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档