Straw's B1og.

Tea类型加密

字数统计: 1.5k阅读时长: 8 min
2023/11/01

Tea类型加密

​ 很早就想概括tea类型加密了,对于很多刚开始做逆向的新手来说,这个掌握好了解题确实快,不像之前的我找到了key,密文,算法,还是因为小错误,而解不出来。作为最基础,也是最常见的加密,确实需要好好总结一番的喵~!

taffychayao

Tea

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void encrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
for (int i = 0; i < 32; i++) {
sum += delta;
l += ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
r += ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
}
v[0] = l;
v[1] = r;
}

void decrypt(unsigned int* v, unsigned int* key) {
unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
sum = delta *32;
for (int i = 0; i < 32; i++) {
r -= ((l << 4) + key[2]) ^ (l + sum) ^ ((l >> 5) + key[3]);
l -= ((r << 4) + key[0]) ^ (r + sum) ^ ((r >> 5) + key[1]);
sum -= delta;
}
v[0] = l;
v[1] = r;
}

其实是一个移位+错位+异或操作结合的算法,逆向解密也是十分容易,将flag以4个unsigned char为一组转为unsigned int加密,注意小端序。

给出一个我常用的解密脚本

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
#include<stdio.h>
int main(){
int n;//pw的个数
unsigned int pw[]={};//可改
unsigned int v0;
unsigned int v1;
unsigned int sum;
unsigned int key[4]={1,2,3,4};//可改
for(int i=0;i<n/2;i++)
{
v0=pw[2*i];
v1=pw[2*i+1];
sum=-32*0x61C88647;
for(int i=0;i<32;i++)
{
v1 -= ((v0 >> 5) + key[3] )^ (16 * v0 + key[2]) ^ (sum + v0);//容易魔改
v0 -= ((v1 >> 5) + key[1]) ^ (16 * v1 + key[0]) ^ (sum + v1);
sum += 0x61C88647;//容易魔改
}
for (int j = 0; j<=3; j++)
{
printf("%c", (v0 >> (j * 8)) & 0xFF);
}
for (int j = 0; j<=3; j++)
{
printf("%c", (v1 >> (j * 8)) & 0xFF);
}
}
}

大多数题目都是给出偶数个unsigned int(4个字节)的密文m,每两段为一组,每一段密文对应的都是4个字母的flag。

这里再给一个python的脚本(我不怎么常用)

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
from ctypes import * 
from Crypto.Util.number import *
def encrypt(v,k):#加密
v0=c_uint32(v[0])
v1=c_uint32(v[1])
sum1=c_uint32(0)
delta=0x9e3779b9
for i in range(32):
sum1.value+=delta
v0.value+=((v1.value<<4)+k[0])^(v1.value+sum1.value)^((v1.value>>5)+k[1])
v1.value+=((v0.value<<4)+k[2])^(v0.value+sum1.value)^((v0.value>>5)+k[3])
return v0.value,v1.value

def decrypt(v,k):#解密
v0=c_uint32(v[0])
v1=c_uint32(v[1])
delta=0x9e3779b9
sum1=c_uint32(delta*40)
for i in range(40):
v1.value-=((v0.value<<5)+k[2])^(v0.value+sum1.value)^((v0.value>>5)+k[3])
v0.value-=((v1.value<<5)+k[0])^(v1.value+sum1.value)^((v1.value>>5)+k[1])
sum1.value-=delta
return v0.value,v1.value

if __name__=='__main__':
k=[2,0,2,3]
# res=encrypt(a,k)
flag=b''
res=[0x76B9621A, 0xCCE4ADDE, 0x25C8BFC8, 0x16C2D472, 0xF317D53A, 0xF2A111A1, 0xDF89F0E6, 0xDCCDA623, 0x21C2F409, 0xDBD88D63]
for i in range(len(res)//2):
d = decrypt(res[2*i:2*(i+1)], k)
flag += long_to_bytes(d[0])[::-1]+long_to_bytes(d[1])[::-1]
flag += long_to_bytes(res[-1])[::-1]
print(flag)

xTea

其实跟tea差不多,只是加密方式变了一下

简单给出加密方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
unsigned int n;
unsigned int flag[n];
unsigned int key[4];
unsigned int v0,v1;
unsigned int delta = 0x9E3779B9;
for (int j = 0; j < n; j=j+2)
{
v0 = flag[j], v1 = flag[j+1]
unsigned sum = 0;
for (int i = 0; i < 32; i++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
}
flag[j] = v0; flag[j+1] = v1;
}

下面是解密脚本

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
#include<stdio.h>
int main()
{
unsigned int enc[] = {};
int n;//enc的个数
unsigned int key[4] = {};
int i, j;
long sum = 0, delta = 0x31415927;//0x9e3779b9=-0x31415927
for(i=0;i <n;i+=2)
{
sum = (32 * delta);
for(j = 0; j < 32; j++)
{
sum -= delta;
enc[i] -= (((enc[i+1] >> 5) ^ (16 * enc[i+1])) + enc[i+1]) ^ (key[(sum & 3)] + sum);//容易魔改
enc[i+1] -= (((enc[i] >> 5) ^ (16 * enc[i])) + enc[i]) ^ (key[((sum >> 11) & 3)] + sum);//容易魔改
}
}
// 打印
for (i = 0; i <n; i++)
{
for (j = 0; j<=3; j++)
{
printf("%c", (enc[i] >> (j * 8)) & 0xFF);
}
}
return 0;
}

xxTea

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void xxtea_encrypt(unsigned int *v, int n, unsigned int key[4]) {
unsigned int y, z, sum;
unsigned int delta=0x9e3779b9
unsigned int p, rounds, e;
rounds = 6 + 52 / n;
sum = 0;
z = v[n - 1];
do {
sum += delta;
e = (sum >> 2) & 3;
for (p = 0; p < n - 1; p++) {
y = v[p + 1];
z = v[p] += (y >> 5 ^ (z << 2)) + (y << 3 ^ (z >> 4)) ^ (sum ^ y) + (key[(p & 3) ^ e] ^ z);
}
y = v[0];
z = v[n - 1] += (y >> 5 ^ (z << 2)) + (y << 3 ^ (z >> 4)) ^ (sum ^ y) + (key[(p & 3) ^ e] ^ z);
} while (--rounds);
}//chatgpt跑的

脚本

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
#include <stdio.h>
#include <stdlib.h>
#define delta 0x9e3779b9

int main()
{
unsigned int v[8] = {0x10BD3B47, 0x6155E0F9, 0x6AF7EBC5, 0x8D23435F, 0x1A091605, 0xD43D40EF, 0xB4B16A67, 0x6B3578A9};//可改
unsigned int key[4] = {0x00001234, 0x00002345, 0x00004567, 0x00006789};//可改
unsigned int sum = 0;
unsigned int y,z,p,rounds,e;
int n = 8;//v的个数
int i = 0;
rounds = 6 + 52/n;//容易魔改
y = v[0];
sum = rounds*delta;
do
{
e = sum >> 2 & 3;
for(p=n-1;p>0;p--)
{
z = v[p-1];
v[p] -= ((((z>>5)^(y<<2))+((y>>3)^(z<<4))) ^ ((key[(p&3)^e]^z)+(y ^ sum)));//容易魔改
y = v[p];
}
z = v[n-1];
v[0] -= (((key[(p^e)&3]^z)+(y ^ sum)) ^ (((y<<2)^(z>>5))+((z<<4)^(y>>3))));//容易魔改
y = v[0];
sum = sum-delta;
}while(--rounds);
for(i=0;i<n;i++)
{
printf("%c%c%c%c",*((char*)&v[i]+0),*((char*)&v[i]+1),*((char*)&v[i]+2),*((char*)&v[i]+3));
//printf("%c%c%c%c",*((char*)&v[i]+3),*((char*)&v[i]+2),*((char*)&v[i]+1),*((char*)&v[i]+0));
}
return 0;
}

例题

2023极客大挑战myslef(tea)

myself

SMC后明显一个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
26
27
28
29
#include<stdio.h>
int main(){
unsigned int pw[8]={0xBDBDF9F0, 0xE26194C4, 0x80799125, 0x1F0FC219, 0xEB6A1815, 0x84F572C5, 0x40CC3A85, 0xD2A32ABB};
unsigned int v0;
unsigned int v1;
unsigned int sum;
unsigned int key[4]={2,2,3,4};
for(int i=0;i<4;i++)
{
v0=pw[2*i];
v1=pw[2*i+1];
sum=-32*0x61C88647;
for(int i=0;i<32;i++)
{
v1 -= ((v0 >> 5) + key[3] )^ (16 * v0 + key[2]) ^ (sum + v0);//容易魔改
v0 -= ((v1 >> 5) + key[1]) ^ (16 * v1 + key[0]) ^ (sum + v1);
sum += 0x61C88647;//容易魔改
}
for (int j = 0; j<=3; j++)
{
printf("%c", (v0 >> (j * 8)) & 0xFF);
}
for (int j = 0; j<=3; j++)
{
printf("%c", (v1 >> (j * 8)) & 0xFF);
}
}
}
//SYC{H0w_7o_R@te_YOurs31f_iNtRo?}

baibai

CATALOG
  1. 1. Tea类型加密
    1. 1.1. Tea
    2. 1.2. xTea
    3. 1.3. xxTea
    4. 1.4. 例题
      1. 1.4.1. 2023极客大挑战myslef(tea)