Rc4加密
Rc4加密算法
介绍
RC4是一种对称加密,其算法简单,运行速度较快,且密钥可变(当长度长于128bit时,就无法暴力破解了),包含初始化算法KSA和加密算法两大部分
加密概述
- 初始化S盒(1~256),初始化T盒,用密钥进行循环进行第一次S交换
- 用S和T进行生成密钥流,进行S的第二次交换
- S和T生成密钥流与明文进行加密
#include <stdio.h>
#include <string.h>
unsigned char sbox[256] = { 0 };
void swap(unsigned char* a, unsigned char* b)
{
unsigned char tmp = *a;
*a = *b;
*b = tmp;
}
//KSA初始化
void init_sbox( unsigned char key[]) {
for (unsigned int i = 0; i < 256; i++)//初始化S表
sbox[i] = i;
unsigned int keyLen = strlen((char*)key);
unsigned char Ttable[256] = { 0 };
for (int i = 0; i < 256; i++)
Ttable[i] = key[i % keyLen];//根据初始化t表
for (int j = 0, i = 0; i < 256; i++)
{
j = (j + sbox[i] + Ttable[i]) % 256; //打乱s盒
swap(sbox[i], sbox[j]); //第一次打乱S表
}
}
//加密算法
void RC4_enc_dec(unsigned char data[],unsigned char key[]){
unsigned char k, i = 0, j = 0, t;
init_sbox(key);
unsigned int dataLen = strlen((char*)data);
for (unsigned h = 0; h < dataLen; h++)
{
i = (i + 1) % 256; //固定方式i
j = (j + sbox[i]) % 256; //固定方式i
swap(sbox[i], sbox[j]); //第二次交换
t = (sbox[i] + sbox[j]) % 256;
k = sbox[t]; //求密钥流,并对明文加密
data[h] ^= k;
}
}
int main()
{
unsigned char data[1000] = { 0 };
unsigned char key[100] = { 0 };
printf("请输入需要加密的明文:\n");
scanf("%s", data);
printf("请输入密钥key:\n");
scanf("%s", key);
RC4_enc_dec(data, key);
printf("加密后的密文是:\n,%s",data);
RC4_enc_dec(data, key);
printf("解密后的明文是:\n%s", data);
return 0;
}
识别方式
- 多次循环次数为256,取模为256
- 最后处理数据为异或
常见魔改
-
魔改初始化算法:S盒初始值不是0-255(可以改成其他值),在置换过程中加入可逆运算(例如异或)
unsigned char tmp = *a; *a = *b; *b = tmp^0x36; -
在最后结果中加入异或等可逆算法
小端存储:数据的高位是大地址(后面),大端存储反之
例题
极客大挑战2021easypyc
以下是逆向出py文件后的内容
# uncompyle6 version 3.8.0
# Python bytecode 3.8.0 (3413)
# Decompiled from: Python 3.8.10 (default, Sep 28 2021, 16:10:42)
# [GCC 9.3.0]
# Embedded file name: easypyc.py
whatbox = [
0] * 256
def aaaaaaa(a, b):
k = [
0] * 256
t = 0
for m in range(256):
whatbox[m] = m
k[m] = ord(a[(m % b)])
else:
for i in range(256):
t = (t + whatbox[i] + k[i]) % 256
temp = whatbox[i]
whatbox[i] = whatbox[t]
whatbox[t] = temp
def bbbbbbbbbb(a, b):
q = 0
w = 0
e = 0
for k in range(b):
q = (q + 1) % 256
w = (w + whatbox[q]) % 256
temp = whatbox[q]
whatbox[q] = whatbox[w]
whatbox[w] = temp
e = (whatbox[q] + whatbox[w]) % 256
a[k] = a[k] ^ whatbox[e] ^ 102
def ccccccccc(a, b):
for i in range(b):
a[i] ^= a[((i + 1) % b)]
else:
for j in range(1, b):
a[j] ^= a[(j - 1)]
if __name__ == '__main__':
kkkkkkk = 'Geek2021'
tttttt = [117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87]
ssss = input('Please input your flag:')
inp = [0] * len(ssss)
if len(ssss) != 32:
print('Length Error!!!!')
exit(0)
for i in range(len(ssss)):
inp[i] = ord(ssss[i])
else:
aaaaaaa(kkkkkkk, len(kkkkkkk))
bbbbbbbbbb(inp, 32)
ccccccccc(inp, 32)
for m in range(32):
if tttttt[m] != inp[m]:
raise Exception('sorry your flag is wrong')
print('success!!!!!!')
print('your flag is {}'.format(ssss))
两个魔改点
-
a[k] = a[k] ^ whatbox[e] ^ 102,在结果前加入可逆的运算
-
ccccccccc(a, b),不可逆的修改结果,整个加密过程不可逆
但由于b魔改后的运算依然可逆,我们无需更改,但是需要改cde运算
更改如下
whatbox = [0] * 256 #生成256长度的数组 def aaaaaaa(a, b): #初始化S盒whatbox k = [0] * 256 t = 0 for m in range(256): whatbox[m] = m k[m] = ord(a[(m % b)]) else: for i in range(256): t = (t + whatbox[i] + k[i]) % 256 temp = whatbox[i] whatbox[i] = whatbox[t] whatbox[t] = temp def bbbbbbbbbb(a, b): q = 0 w = 0 e = 0 for k in range(b): q = (q + 1) % 256 w = (w + whatbox[q]) % 256 temp = whatbox[q] whatbox[q] = whatbox[w] whatbox[w] = temp e = (whatbox[q] + whatbox[w]) % 256 a[k] = a[k] ^ whatbox[e] ^ 102 print(chr(a[k]), end='') def ccccccccc(a, b): for j in range(b - 1, 0, -1): a[j] ^= a[(j - 1)] else: for i in range(b - 1, -1, -1): a[i] ^= a[((i + 1) % b)] if __name__ == '__main__': kkkkkkk = 'Geek2021' tttttt = [117, 62, 240, 152, 195, 117, 103, 74, 240, 151, 173, 162, 17, 75, 141, 165, 136, 117, 113, 33, 98, 151, 174, 4, 48, 25, 254, 101, 185, 127, 131, 87] ccccccccc(tttttt, 32) aaaaaaa(kkkkkkk, len(kkkkkkk)) bbbbbbbbbb(tttttt, 32) for……else当for能够正常执行时,运行else内的代码块

浙公网安备 33010602011771号