Re中常见的加密算法

常见的加密算法

Base64

简介

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。

规则

把3个字节(3*8bit)变成4个字节(4*6bit),然后把6Bit再添两位高位0,组成四个8bit的字节

字母表如下
alphabet
需要注意的是,在CTF题目中,有些题目索引表会做出改变

特点

当反编译发现字母表时,可能存在base64编码,需要注意的是,CTF中base64的索引表可能被更换

脚本

1
2
3
4
5
6
import base64
my_base64table = ""#新的索引表
std_base64table ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
s = ""#密文
s = s.translate(str.maketrans(my_base64table,std_base64table))
print(base64.b64decode(s))

Tea

简介

在密码学中,微型加密算法(Tiny Encryption Algorithm,TEA)是一种易于描述和执行的块密码,通常只需要很少的代码就可实现。其设计者是剑桥大学计算机实验室的大卫 · 惠勒与罗杰 · 尼达姆。

规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdint.h>

void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}

void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schedule constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}

特点

Tea算法比较简单,且可以根据需求设置不同加密轮数来增加加密强度。
最主要的识别特征为delta = 0x9e3779b9

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
class MyTea:
def __init__(self, key):
assert(type(key) == bytes)
assert(len(key) == 16)
self.k = [0]*4
for i in range(4):
self.k[i] = self.btoi(key[4*i:4*i+4])

@staticmethod
def btoi(b):
return int.from_bytes(b, byteorder="little", signed=False)

@staticmethod
def itob(i):
return int.to_bytes(i, 4, "little")

def decrypt(self, ciphertext: bytes):
plaintext = b''
for i in range(len(ciphertext)//8):
plaintext += self.decrypt_8_char(ciphertext[i*8:i*8+8])
return plaintext

def decrypt_8_char(self, sub_str):
assert(type(sub_str) == bytes)
assert(len(sub_str) == 8)
v0 = self.btoi(sub_str[:4])
v1 = self.btoi(sub_str[4:])
delta = 0x9e3779b9
sum = delta * 32
sum &= 0xffffffff
for _ in range(32):
v1 -= ((v0 << 4) + self.k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + self.k[3])
v1 &= 0xFFFFFFFF
v0 -= ((v1 << 4) + self.k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + self.k[1])
v0 &= 0xFFFFFFFF
sum -= delta
sum &= 0xffffffff

return self.itob(v0)+self.itob(v1)


if __name__ == "__main__":
cipher = [int.to_bytes(n, 1, "little")for n in [ ]]#密文
cipher=b''.join(cipher)
key = b''#密钥
t = MyTea(key)

plain = t.decrypt(cipher)
print(plain)

RC4

简介

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

规则

RC4生成一种称为密钥流的伪随机流,它同明文通过异或操作以达到加密的目的,伪代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void rc4_init(unsigned char *s, unsigned char *key, unsigned long Len) //初始化函数
{
int i =0, j = 0;
char k[256] = {0};
unsigned char tmp = 0;
for (i=0;i<256;i++) {
s[i] = i;
k[i] = key[i%Len];
}
for (i=0; i<256; i++) {
j=(j+s[i]+k[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[i]和s[j]
s[j] = tmp;
}
} //密钥调度算法,用0-255初始化数组S,然后用密钥进行替换

void rc4_crypt(unsigned char *s, unsigned char *Data, unsigned long Len) //加解密
{
int i = 0, j = 0, t = 0;
unsigned long k = 0;
unsigned char tmp;
for(k=0;k<Len;k++) {
i=(i+1)%256;
j=(j+s[i])%256;
tmp = s[i];
s[i] = s[j]; //交换s[x]和s[y]
s[j] = tmp;
t=(s[i]+s[j])%256;
Data[k] ^= s[t];
} //对每个S[i]根据当前的值与S中的另一元素替换,得到的密钥流与明文进行异或操作
}

特点

2个长度为256的For循环
S盒乱序时的数据交换
异或加解密

脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
from Crypto.Cipher import ARC4
from binascii import b2a_hex, a2b_hex
def myRC4(data,key):
rc41 = ARC4.new(key)
encrypted = rc41.encrypt(data)
return encrypted.encode('hex')
def rc4_decrpt_hex(data,key):
rc41=ARC4.new(key)S
return rc41.decrypt(a2b_hex(data))
key=''
data=r''
print myRC4(data,key)
print rc4_decrpt_hex('e79aaf7a42d9a1',key)

MD5

简介

一种被广泛使用的密码散列函数,可以产生16字节的散列值

规则

(1)数据填充
填充消息使其长度与448模512同余,方法是附一个1在后面,然后用0填充。
(2)添加长度
附上64位消息长度,使之成为512的整数倍
(3)初始化变量(MD5Init())
初始化A=0x01234567,B=0x89ABCDEF,C=0xFEDCBA98,D=0x76543210用来计算。
(4)数据处理(MD5Update()、MD5Final())
主循环有四轮,每轮循环都很相似。第一轮进行16次操作。每次操作对a、b、c和d中的其中三个作一次非线性函数运算,然后将所得结果加上第四个变量,文本的一个子分组和一个常数。再将所得结果向左环移一个不定的数,并加上a、b、c或d中之一。最后用该结果取代a、b、c或d中之一。
以下是每次操作中用到的四个辅助函数(每轮一个)。
F( X ,Y ,Z ) = ( X & Y ) | ( (X) & Z )
G( X ,Y ,Z ) = ( X & Z ) | ( Y & (
Z) )
H( X ,Y ,Z ) =X ^ Y ^ Z
I( X ,Y ,Z ) =Y ^ ( X | (~Z) )

特点

四个常数
h0 = 0x67452301;
h1 = 0xefcdab89;
h2 = 0x98badcfe;
h3 = 0x10325476;
MD5变形:改变4个常数、改变填充的方法、改变hash变换的处理过程