RC4算法原理及C++实现

  • RC4加密原理
    • 流密码RC4
    • C++代码中问题解决
    • 在代码实现中可能的问题:
  • IDA逆向分析
    • RC4算法魔改
    • IDA中的变量分配问题
  • 源代码
    • 参考

RC4加密原理

流密码RC4

在密码学中,RC4(来自Rivest Cipher 4的缩写)是一种串流加密法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法
整体加密流程:

RC4的加密核心主要是一步异或(明文与秘钥流进行逐字节异或),主要算法在秘钥流的生成方面。首先初始化一个S盒(一个无符号字符型,大小为256的数组),根据秘钥key(可自定,也可用伪随机数生成)生成一个T向量(同样为无符号字符型256大小)

 unsigned char s[256];unsigned char t[256];for(int i=0;i<256;i++){ //初始化S盒和t向量 s[i]=i;t[i]=key[i%keylen]; //秘钥key及其长度}

通过T向量打乱S盒

 int j = 0;for(int i=0;i<256;i++){j=(j+s[i]+t[i])%256;swap(s[i],s[j]);  //根据t向量打乱s盒 ,交换是s[i]和是[j]  循环256次 S盒内大部分顺序被打乱}

下一步,生成秘钥流,可以将秘钥流与明(密)文直接异或 ,或者存放到一个大小为mlen的无符号字符型数组中。

 unsigned char k[mlen];//保存秘钥流,或者直接进行异或 int i=0; j=0; int tmp;for(int index=0;index<mlen;index++){   //生成与明文长度一致的秘钥流 i=(i+1)%256;   //明文长度可能超过256,不能直接i++j=(j+s[i])%256;swap(s[i],s[j]);tmp=(s[i]+s[j])%256;k[index]=s[tmp];//保存秘钥 }

最后将生成的秘钥流与明文进行逐字节异或

for(i=0;i<mlen;i++)m[i]=m[i]^k[i];//主要进行了一步异或

分析上述过程,在生成秘钥流的过程中只有KEY参与,所以相同key生成的秘钥流一致,而最终只是秘钥流与明文进行了逐字节异或,根据异或的特征,故加密和解密公用一套算法。

同时,RC4加密的安全性与key的长度也有着关系,key太短,则容易被爆破,key太长(>256)则多余字节根本没有参与加密,一般key的选择在128字节左右就够用并且是安全的。

整体流程代码:

int main(){  //加密的主函数unsigned char flag[]="需要加密的数据";char key[]="秘钥";RC4_encrypt(flag,key,sizeof(flag)-1,strlen(key));for(int i=0;i<sizeof(flag)-1;i++)cout<<(int)flag[i]<<",";return 0;
} void RC4_encrypt(unsigned char *m, char *key,int mlen,int keylen){unsigned char s[256];unsigned char t[256];for(int i=0;i<256;i++){ //初始化s和t向量 s[i]=i;t[i]=key[i%keylen];}int j = 0;for(int i=0;i<256;i++){j=(j+s[i]+t[i])%256;swap(s[i],s[j]);  //根据t向量打乱s盒 }unsigned char k[mlen];//保存秘钥流,或者直接进行异或 int i=0; j=0; int tmp;for(int index=0;index<mlen;index++){   //生成与明文长度一致的秘钥流 i=(i+1)%256;j=(j+s[i])%256;swap(s[i],s[j]);tmp=(s[i]+s[j])%256;k[index]=s[tmp];//保存秘钥 } for(i=0;i<mlen;i++){    m[i]=m[i]^k[i];//主要进行了一步异或,加密的逆过程就是解密 }}

c++/c中int和char类隐式转换十分方便(通过ASCII码),这样方便统计长度和进行格式转换。

C++代码中问题解决

在代码实现中可能的问题:

为什么要用unsigned char,与char同为 1个字节大小,但是整数的范围不同 unsigned char的范围才是我们要的0~255 而 单纯char的话第一位为符号位 所以为 -128 到 127,这里最好要用无符号char

另外就是在主函数中的调用:

 unsigned char flag[]={109,0,85,138,95,219,19,35,59,20,97,8,73,15,81,201,242};char key[]="keykeykey";RC4_encrypt(flag,key,sizeof(flag),strlen(key));cout<<flag<<endl;return 0;

在解密过程中,密文数组中可能会有0,根据strlen的原理是遇到‘\0’就停止可能出现错误,并且密文数组定义为了unsigned char类型,不能用strlen函数来判断长度,所以这里用sizeof来代替,当然key数组最好也定义为unsigned char类型,这里便不再展示。
如果是{xx,xx}则sizeof表示正常大小,如果是“aaaa”,则sizeof表示长度为5(多了一个0)注意细节。

IDA逆向分析

完善主函数,生成的EXE文件拖入IDA64中分析。
简单写了一个对输入进行一个RC4加密之后和v7(如果IDA给v7开辟的int型数组,注意小端序)串进行比较,key直接给了。
初始化S盒和T盒与变异的RC4算法

RC4算法魔改

一般魔改的RC4主要是S盒和T盒的初始化方面,正常的初始化S盒是0-255 而T盒则是key循环填进去
曾经遇到过将S盒的初始化改为255-i,解密只需要以相同初始化方式即可

swap交换函数内部

接下来便是打乱S盒和生成秘钥流。
v8=v6有点诡异,但看他们在栈中的空间,v8是rsp+228h v6是rsp+20h,差值是208h为520故,v8和v6也是没有交集的空间,其余则是生成秘钥流和进行异或了。

IDA中的变量分配问题


可知IDA反编译对数组的处理,一般开辟的空间要比原空间大,并且可能产生一些不同,比如v7也就是secret,我们自定义的是17大小,而开辟了32个大小,并且unsigned char型变成了char型,所以v7看起来会有一些负数值。同样,key数组的大小和flag数组的大小都开辟的了大了许多,但参与运算的数量并没有变化。

源代码

实现上可能有些不足或缺陷,还望指正。

#include<iostream>
#include<cstring>
using namespace std;
void swap(int &a,int &b); //flag{This_is_RC4}
void RC4_encrypt(unsigned char *m, char *key,int mlen,int keylen);
int main(){unsigned char flag[18];cout<<"tell me your secret:";cin>>flag; int len=17;char key[]="keykeykey";RC4_encrypt(flag,key,len,strlen(key));unsigned char secret[17]={109,0,85,138,95,219,19,35,59,20,97,8,73,15,81,201,242};for(int i=0;i<len;i++){if(secret[i]!=flag[i]){cout<<"try again!"<<endl;return 0;}}cout<<"you get it!"<<endl;  return 0;
} void swap(int &a,int &b){int temp;temp=a;a=b;b=temp;
}void RC4_encrypt(unsigned char *m, char *key,int mlen,int keylen){unsigned char s[256];unsigned char t[256];for(int i=0;i<256;i++){ //初始化s和t向量 s[i]=i;t[i]=key[i%keylen];}int j = 0;for(int i=0;i<256;i++){j=(j+s[i]+t[i])%256;swap(s[i],s[j]);  //根据t向量打乱s盒 }unsigned char k[mlen];//保存秘钥流,或者直接进行异或 int i=0; j=0; int tmp;for(int index=0;index<mlen;index++){   //生成与明文长度一致的秘钥流 i=(i+1)%256;j=(j+s[i])%256;swap(s[i],s[j]);tmp=(s[i]+s[j])%256;k[index]=s[tmp];//保存秘钥 } for(i=0;i<mlen;i++){    m[i]=m[i]^k[i];//主要进行了一步异或,加密的逆过程就是解密 }}

参考

流密码和RC4:https://www.cnblogs.com/block2016/p/5601925.html
密码学基础和RC4:https://www.jianshu.com/p/f22a98eb437f
维基百科-RC4

RE-RC4加密分析相关推荐

  1. 江湖rc4加密分析源代码

    参数 定义 data 加密解密的文本 key 加密秘钥 t 0=加密 1=解密 function rc4(data,key,t) {var pwd = key || 'ffsirllq';var ci ...

  2. 19 crypto-js RC4 加密的具体处理

    前言 这里主要是关于 RC4 加密的相关调研 之所以调研这个是因为之前存在一个问题, 调用 java 相关 api 进行 RC4 加密的结果 和调用 crypto-js 的结果不一样, 作为出发点开始 ...

  3. java实现rc4密码_java实现RC4加密解密的实例教程

    这篇文章主要介绍了java实现的RC4加密解密算法,结合具体实例形式分析了java RC4加密解密算法的实现与使用技巧,需要的朋友可以参考下 本文实例讲述了java实现的RC4加密解密算法.分享给大家 ...

  4. go RC4加密解密

    总结: 1. RC4加密和解密公用一个函数,即 XORKeyStream() 2. 加密和解密不能用同一个Cipher对象,必须重新生成一个,否则失败 3. XORKeyStream()的两个参数,可 ...

  5. RC4加密解密java算法

    有一个项目,需要解析一个用户提供的rc4加密后的文件,特意搜索整理了一个java 版本的RC4加解密算法. public static String HloveyRC4(String aInput,S ...

  6. 【JS 逆向百例】X球投资者社区 cookie 参数 acw_sc__v2 加密分析

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 文章目录 声明 逆向目标 抓包分析 加密查找 参数逆向 完整代码 JavaScript 加密代码 Python 测试代码 声明 ...

  7. 【JS 逆向百例】Ether Rock 空投接口 AES256 加密分析

    关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...

  8. python爬虫加密空间_Python爬虫进阶必备 | XX同城加密分析

    目标网站: aHR0cHM6Ly9wYXNzcG9ydC41OC5jb20vbG9naW4vP3BhdGg9aHR0cHMlM0EvL2Z6LjU4LmNvbS8mUEdUSUQ9MGQxMDAwMD ...

  9. Python 爬虫进阶必备——某体育网站登录令牌加密分析,赶紧收藏哦!

    某体育网站登录令牌加密分析 aHR0cHMlM0EvL3d3dy55YWJvMjU5LmNvbS9sb2dpbg== 这个网站需要分析的是登录时候的 sign令牌 抓包与加密定位 老规矩先用开发者工具 ...

最新文章

  1. 2019.3.18 异常处理和日志相关
  2. 读书笔记《锋利的jQuery》
  3. [转]asp.net文件下载方法...
  4. Codeforce_732
  5. Leetcode 242.有效的字母异位词(哈希表)
  6. stm32 SPI、FLASH
  7. Python用类求圆的周长面积与球的表面积体积
  8. 如何通俗易懂地解释卷积?(2)
  9. 【机器人】四元数与旋转矩阵的转换关系
  10. 拓端tecdat|R语言分位数回归预测筛选有上升潜力的股票
  11. vue-router 修改或添加新参数
  12. 【计算机图形学】Bezier曲线软件及操作
  13. nginx 通过域名代理tcp端口
  14. lucene--简介
  15. ubuntu相关软件安装
  16. SIP语音对讲从零到整之(一)sip介绍
  17. python设备分组(部门分组等)功能设计
  18. 机器学习模型常用性能指标和Python代码实现
  19. mysql修改初始密码....
  20. LeetCode刷题(37)~无重复字符的最长子串

热门文章

  1. 猫猫向前冲 Week8作业B题
  2. 关于Win32 Aplication与Win32 console Aplication ------开始一篇
  3. vr全景制作常用的app有哪些,vr全景拍摄真的难吗?
  4. 烤仔同传 | 富豪收割机是怎样炼成的?麦道夫“巫术”大揭秘
  5. 鼠标右键添加新建.md文档(亲测成功)
  6. java mvp设计模式_MVP设计模式
  7. 534 java后台写法
  8. android控件复制,修改Delphi 10.1.2 edit控件在android的复制、剪切和粘贴样式
  9. 安全生产危化品经营单位安全管理人员一[安考星]
  10. 欧盟运营商:网络中立性规则危及5G投资