TEA

TEA在加密的过程中要加密的明文使用2个32位无符号整数(2×4字节),秘钥为4个32位无符号整数(4×4字节),更长的明文可通过分为多个4字节为单位的小组分别进行加密(循环)

在逆向分析实战中判断TEA算法的可从其3行核心加密中出现的右移4左移5,两行各有3个小括号互相异或的加密流程单次加密循环32次以及运算中出现的sumdelta变量看出

下面是TEA算法加密过程的C语言代码实现

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
#include <stdio.h>
#include <stdint.h>
void encrypt(uint32_t* temp, uint32_t* key)// 加密函数
{
uint32_t v0 = temp[0], v1 = temp[1];// v0、v1分别是明文的左、右半部分
int sum = 0; // sum用作加密过程中的一个累加变量
uint32_t delta = 0x9e3779b9; // 作为sum每次累加的变化值,题目中往往会修改此值
for (int i = 0; i < 32; i++)
{
//以下3行是核心加密过程,题目中可能会对部分细节做出修改
//但由于异或的对称性质,无需记忆,写解密函数时照抄即可
v1 += ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]);
v0 += ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]);
sum += delta;
}
temp[0] = v0;
temp[1] = v1;
}

int main()
{
uint32_t key[4] =
{
// 此处存放密钥
};
uint32_t temp[2]; // 存储每组明文
uint8_t flag[32] =
{
// 此处存放要加密的数据
};
for (int i = 0; i < 32; i += 8)
{
temp[0] = *(uint32_t*)&flag[i];
temp[1] = *(uint32_t*)&flag[i + 4];// 设置每组明文

encrypt(temp, key);// 调用加密函数

for (int j = 0; j < 2; j++) // 输出加密后的数据
{
for (int m = 0; m < 4; m++)
{
printf("%c", temp[j] & 0xff); // 按字节输出
temp[j] >>= 8;
}
}
}
return 0;
}

下面是TEA算法解密过程的C语言代码实现

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
#include <stdio.h>
#include <stdint.h>
void decrypt(uint32_t* temp, uint32_t* key) // 解密函数
{
uint32_t v0 = temp[0], v1 = temp[1];
int sum = 0x9e3779b9 * 32; // 初始sum值,注意此处要修改为delta的32倍
uint32_t delta = 0x9e3779b9; // 和加密函数一致的delta常量
for (int i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + key[2]) ^ (v0 + sum) ^ ((v0 >> 5) + key[3]);// 不要修改算式!
v0 -= ((v1 << 4) + key[0]) ^ (v1 + sum) ^ ((v1 >> 5) + key[1]);
sum -= delta;
}
temp[0] = v0;
temp[1] = v1;
}

int main() {
uint32_t key[4] =
{
// 此处存放密钥
};
uint32_t temp[2]; // 存储每组密文
uint8_t flag[32] =
{
// 此处存放要解密的数据
};

for (int i = 0; i < 32; i += 8)
{
temp[0] = *(uint32_t*)&flag[i];
temp[1] = *(uint32_t*)&flag[i + 4];

decrypt(temp, key);// 调用解密函数

for (int j = 0; j < 2; j++) // 输出解密后的数据
{
for (int m = 0; m < 4; m++)
{
printf("%c", temp[j] & 0xff); // 按字节输出,恢复原始字符
temp[j] >>= 8;
}
}
}
return 0;
}