RC4加密算法逆向分析
简介
RC4 是一种流加密算法,密钥长度可变。它加解密使用相同的密钥,因此也属于对称加密算法。RC4 是有线等效加密(WEP)中采用的加密算法,也曾经是 TLS 可采用的算法之一。
加解密原理
RC4 由伪随机数生成器和异或运算组成(由于异或运算的对合性,RC4 加密解密使用同一套算法)。RC4 的密钥长度可变,范围是[1,255]
。RC4 一个字节一个字节地加解密。给定一个密钥,伪随机数生成器接受密钥并产生一个 S 盒。S 盒用来加密数据,而且在加密过程中 S 盒会变化。
加密流程
先初始化状态向量
S
(256 个字节,用来作为密钥生成的种子)按照升序,给每个字节赋值。初始密钥(由用户输入),长度任意,如果输入长度小于 256 个字节,则进行轮转,直到填满。例如填入密钥的是1 2 3 4 5 ,那么填入的是1,2,3,4,5,1,3,4,5,1,2,3,4,5 由上述轮转过程得到 256 个字节的向量
T
(用来作为密钥流生成的种子)最后是根据向量
S
和T
生成T
生成密钥流与明文进行加密
1 |
|
C代码表示
几个基本变量:
- S-Box也就是所谓的
S
盒,是一个 256 长度的char
型数组,每个单元都是一个字节,算法运行的任何时候,S
都包括0-255的8比特数的排列组合,只不过值的位置发生了变换。 - 密钥
char key[256]
密钥的长度keylen
与明文长度、密钥流的长度没有必然关系。 - 临时向量
k
长度也为 256,每个单元也是一个字节。如果密钥的长度是 256 字节,就直接把密钥的值赋给 k,否则,轮转地将密钥的每个字节赋给k
。
初始化部分
- 参数 1 是一个 256 长度的
char
型数组,定义为:unsigned char sBox[256]
- 参数 2 是密钥,其内容可以随便定义:
char key[256]
- 参数 3 是密钥的长度,
Len=strlen(key)
示例代码:
1 |
|
初始化长度为 256 的S
盒。第一个for
循环将 0 到 255 的互不重复的元素装入S
盒。第二个for
循环根据密钥打乱S
盒,i
确保 S-box 的每个元素都得到处理,j
保证 S-box 的搅乱是随机的。而不同的 S-box 在经过伪随机子密码生成算法的处理后可以得到不同的子密钥序列,将 S-box 和明文进行xor
运算,得到密文,解密过程也完全相同。
加密部分
- 参数1 是上边
rc4_init
函数中,被搅乱的 S-box - 参数2 是需要加密的数据
data
- 参数3 是
data
的长度
示例代码:
1 |
|
每收到一个字节,就进行循环。通过一定的算法定位S
盒中的一个元素,并与输入字节异或,得到k
。循环中还改变了S
盒。如果输入的是明文,输出的就是密文;如果输入的是密文,输出的就是明文。
主函数
示例代码:
1 |
|
完整代码
1 |
|
逆向分析
特征识别
RC4 算法主要通过加密算法特征来进行识别。
反编译后可以看见多个循环次数为 256 的循环,以及存在一些
%256
的运算。最后处理输入数据的是异或。
动态调试解RC4
由于 RC4 是对称加密,加密和解密用的是一套算法。也就是说我们如果将加密后的密文重新利用算法进行再次加密就可以得到明文。
所以对于标准的 RC4 算法我们可以进行对密文再次加密来获取明文。
首先我们要确定加密算法是否为对称加密
然后我们要获取密文,将密文深入进行再次加密
魔改RC4
RC4常见的魔改方法:
魔改初始化算法,可以将
s
盒初始化值并不设置成 0-255,也可以设置成其它的,也可以在s
的初始置换过程中添加可逆运算。由于最后加密 flag 是利用密钥流来单字节加密的,也有人会在这个地方添加一些可逆运算来进行魔改。
例:
总之算法需要遵循对称加密性质。
enc_data=RC4(flag)
flag=RC4(enc_data)
例题
标准RC4
2024Moectf RC4
1 |
|
动态调试解RC4
2024极客大挑战
魔改RC4
YLCTF xorplus
2024极客大挑战