RE-RC4加密分析
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加密分析相关推荐
- 江湖rc4加密分析源代码
参数 定义 data 加密解密的文本 key 加密秘钥 t 0=加密 1=解密 function rc4(data,key,t) {var pwd = key || 'ffsirllq';var ci ...
- 19 crypto-js RC4 加密的具体处理
前言 这里主要是关于 RC4 加密的相关调研 之所以调研这个是因为之前存在一个问题, 调用 java 相关 api 进行 RC4 加密的结果 和调用 crypto-js 的结果不一样, 作为出发点开始 ...
- java实现rc4密码_java实现RC4加密解密的实例教程
这篇文章主要介绍了java实现的RC4加密解密算法,结合具体实例形式分析了java RC4加密解密算法的实现与使用技巧,需要的朋友可以参考下 本文实例讲述了java实现的RC4加密解密算法.分享给大家 ...
- go RC4加密解密
总结: 1. RC4加密和解密公用一个函数,即 XORKeyStream() 2. 加密和解密不能用同一个Cipher对象,必须重新生成一个,否则失败 3. XORKeyStream()的两个参数,可 ...
- RC4加密解密java算法
有一个项目,需要解析一个用户提供的rc4加密后的文件,特意搜索整理了一个java 版本的RC4加解密算法. public static String HloveyRC4(String aInput,S ...
- 【JS 逆向百例】X球投资者社区 cookie 参数 acw_sc__v2 加密分析
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 文章目录 声明 逆向目标 抓包分析 加密查找 参数逆向 完整代码 JavaScript 加密代码 Python 测试代码 声明 ...
- 【JS 逆向百例】Ether Rock 空投接口 AES256 加密分析
关注微信公众号:K哥爬虫,持续分享爬虫进阶.JS/安卓逆向等技术干货! 声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后 ...
- python爬虫加密空间_Python爬虫进阶必备 | XX同城加密分析
目标网站: aHR0cHM6Ly9wYXNzcG9ydC41OC5jb20vbG9naW4vP3BhdGg9aHR0cHMlM0EvL2Z6LjU4LmNvbS8mUEdUSUQ9MGQxMDAwMD ...
- Python 爬虫进阶必备——某体育网站登录令牌加密分析,赶紧收藏哦!
某体育网站登录令牌加密分析 aHR0cHMlM0EvL3d3dy55YWJvMjU5LmNvbS9sb2dpbg== 这个网站需要分析的是登录时候的 sign令牌 抓包与加密定位 老规矩先用开发者工具 ...
最新文章
- 2019.3.18 异常处理和日志相关
- 读书笔记《锋利的jQuery》
- [转]asp.net文件下载方法...
- Codeforce_732
- Leetcode 242.有效的字母异位词(哈希表)
- stm32 SPI、FLASH
- Python用类求圆的周长面积与球的表面积体积
- 如何通俗易懂地解释卷积?(2)
- 【机器人】四元数与旋转矩阵的转换关系
- 拓端tecdat|R语言分位数回归预测筛选有上升潜力的股票
- vue-router 修改或添加新参数
- 【计算机图形学】Bezier曲线软件及操作
- nginx 通过域名代理tcp端口
- lucene--简介
- ubuntu相关软件安装
- SIP语音对讲从零到整之(一)sip介绍
- python设备分组(部门分组等)功能设计
- 机器学习模型常用性能指标和Python代码实现
- mysql修改初始密码....
- LeetCode刷题(37)~无重复字符的最长子串
热门文章
- 猫猫向前冲 Week8作业B题
- 关于Win32 Aplication与Win32 console Aplication ------开始一篇
- vr全景制作常用的app有哪些,vr全景拍摄真的难吗?
- 烤仔同传 | 富豪收割机是怎样炼成的?麦道夫“巫术”大揭秘
- 鼠标右键添加新建.md文档(亲测成功)
- java mvp设计模式_MVP设计模式
- 534 java后台写法
- android控件复制,修改Delphi 10.1.2 edit控件在android的复制、剪切和粘贴样式
- 安全生产危化品经营单位安全管理人员一[安考星]
- 欧盟运营商:网络中立性规则危及5G投资