TEA这段时间遇到的是真多,有直接原始加密,也有 XTEA,XXTEA,更有在此上魔改的,之前也是能认出来,知道还是不够。
en,TEA加密解密脚本还是用 C 好一些,什么溢出之类不用考虑。
TEA
也有可能是 64 轮迭代
def encrypt(v, k):
v0, v1 = v[0], v[1]
sum = 0
delta = 0x9e3779b9
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
for i in range(32):
sum = (sum + delta) & 0xffffffff
v0 = (v0 + (((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1))) & 0xffffffff
v1 = (v1 + (((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3))) & 0xffffffff
return [v0, v1]
#确保它们在 32 位整数范围内
if __name__ == "__main__":
data = [1234, 5678]
key = [1, 2, 3, 4]
enc = encrypt(data, key)
print(enc)
def decrypt(v,k):
v0,v1=v[0],v[1]
delta=0x9e3779b9
k0,k1,k2,k3=k[0],k[1],k[2],k[3]
sum=(delta*32)&0xffffffff
for i in range(32):
v1 = (v1 - (((v0 << 4) + k2) ^ (v0 + sum) ^ ((v0 >> 5) + k3))) & 0xffffffff
v0 = (v0 - (((v1 << 4) + k0) ^ (v1 + sum) ^ ((v1 >> 5) + k1))) & 0xffffffff
sum = (sum - delta) & 0xffffffff
v[0],v[1]=v0,v1
return v
if __name__=="__main__":
data=[731179895, 2211051369]
key=[1,2,3,4]
res=decrypt(data,key)
print(res)
在python中, 最好不要使用 “-=”,和 C 不同,害我改了半天,xp。
XTEA
就是每轮加密不同
def encrypt(v, k):
v0, v1 = v[0], v[1]
sum = 0
delta = 0x9e3779b9
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
for i in range(32):
v0=v0+((((v1<<4) ^ (v1>>5))+v1) ^ (sum+k[sum&3]))&0xffffffff
sum=(sum+delta)&0xffffffff
v1=v1+((((v0<<4) ^ (v0>>5))+v0) ^ (sum+k[(sum>>11)&3]))&0xffffffff
return [v0, v1]
#确保它们在 32 位整数范围内
if __name__ == "__main__":
data = [1234, 5678]
key = [1,2, 3, 4]
enc = encrypt(data, key)
print(enc)
key[sum & 3 ]
sum & 3 保证索引在 k0 到 k3 之间循环, 3 是 ‘11’,故只保留sum后两位
(sum + k[sum & 3])
这个操作首先将 sum
右移 11 位,然后再进行按位与操作 & 3
。这个操作同样可以确保结果在 0 到 3 之间,但它使用的是 sum
的第 12 和 13 位
def encrypt(v, k):
v0, v1 = v[0], v[1]
sum = (0x9e3779b9*32)&0xffffffff
delta = 0x9e3779b9
k0, k1, k2, k3 = k[0], k[1], k[2], k[3]
for i in range(32):
v1 = v1 - ((((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum >> 11) & 3])) & 0xffffffff
sum=(sum-delta)&0xffffffff
v0 = v0 - ((((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3])) & 0xffffffff
return [v0, v1]
#确保它们在 32 位整数范围内
if __name__ == "__main__":
data = [1787803488, 3495090297]
key = [1,2, 3, 4]
enc = encrypt(data, key)
print(enc)
XXTEA
例题:
[HNCTF 2022 WEEK2]TTTTTTTTTea
应该是XTEA加密
key 都是 32位数,故写成四个八位的数组
key=[0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f]
也可以按 D 换成 dw ,dd
唉,没几个大佬分析前面的,是我太菜了!
exp:
大佬都是用 C 写的,确实好写一些好像
为加强理解,我用 python写一个,还是有一点小问题:
enc = [0xC11EE75A, 0xA4AD0973, 0xF61C9018, 0x32E37BCD, 0x2DCC1F26, 0x344380CC]
def decrypt(enc1, enc2):
key = [0x00010203, 0x04050607, 0x08090a0b, 0x0c0d0e0f]
delta = 0x9e3779b9
sum = (delta * 32) & 0xffffffff
for i in range(32):
enc2 = (enc2 - ((((enc1 >> 5) ^ (enc1 << 4)) + enc1) ^ (key[(sum >> 11) & 3] + sum))) & 0xffffffff
sum = (sum - delta) & 0xffffffff
enc1 = (enc1 - ((((enc2 >> 5) ^ (enc2 << 4)) + enc2) ^ (key[sum & 3] + sum))) & 0xffffffff
return enc1, enc2
data = []
for i in range(0, 6, 2):
res1, res2 = decrypt(enc[i], enc[i + 1])
data.append(res1)
data.append(res2)
print(data)
for value in data:
print(chr((value >> 24) & 0xff) + chr((value >> 16) & 0xff) + chr((value >> 8) & 0xff) + chr(value & 0xff), end='')
#CSSNT{FTT_aeT_AET_Ae}+aE
啊!差了一点,去看看哪里有问题,啊,没找到
#include<stdio.h>
int main()
{
unsigned int enc[6] = { 0xC11EE75A, 0xA4AD0973, 0xF61C9018, 0x32E37BCD, 0x2DCC1F26, 0x344380CC };
unsigned int key[4] = { 0x10203, 0x4050607, 0x8090A0B, 0x0C0D0E0F };
int i, j;
long sum = 0, delta = 0x61C88647;
// 解码
for (i = 0; i < 6; i += 2) {
sum = 0 - (32 * delta);
for (j = 0; j < 32; j++) {
enc[i + 1] -= (((enc[i] >> 5) ^ (16 * enc[i])) + enc[i]) ^ (key[((sum >> 11) & 3)] + sum);
sum += delta;
enc[i] -= ((((enc[i + 1] >> 5) ^ (16 * enc[i + 1])) + enc[i + 1]) ^ key[sum & 3] + sum);
}
}
// 打印
for (i = 0; i < 6; i++)
{
for (j = 0; j <= 3; j++)
{
printf("%c", (enc[i] >> (j * 8)) & 0xFF);
}
}
return 0;
}
[MoeCTF 2022]ezTea
#include <stdio.h>
#include <stdint.h>
void encrypt (uint32_t* v, uint32_t* k) { // 主要加密函数,试着搞定它
uint32_t v0 = v[0], v1 = v[1], sum = 0;
uint32_t delta = 0xd33b470;
for (int i = 0; i < 32; i++) {
sum += delta;
v0 += ((v1<<4) + k[0]) ^ (v1 + sum) ^ ((v1>>5) + k[1]);
v1 += ((v0<<4) + k[2]) ^ (v0 + sum) ^ ((v0>>5) + k[3]);
}
v[0] = v0;
v[1] = v1;
}
void decrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0;
uint32_t delta = 0xd33b470*32;
for (int i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
int main() {
uint32_t k[4] = {1, 2, 3, 4};
int8_t input[33] = { 0x17, 0x65, 0x54, 0x89, 0xed, 0x65, 0x46, 0x32, 0x3d, 0x58, 0xa9, 0xfd, 0xe2, 0x5e,
0x61, 0x97, 0xe4, 0x60, 0xf1, 0x91, 0x73, 0xe9, 0xe9, 0xa2, 0x59, 0xcb, 0x9a, 0x99,
0xec, 0xb1, 0xe1, 0x7d };
scanf("%32s", input);
for (int i = 0; i < 32; i+=8) {
uint32_t v[2] = {*(uint32_t *)&input[i], *(uint32_t *)&input[i+4]};
decrypt(v, k);
for (int j = 0; j < 2; j++) { // 这一段主要是把 v 按单字节输出,另外可以了解一下 “大小端序” 在这题是如何体现的
for (int k = 0; k < 4; k++) {
printf("%#x, ", v[j] & 0xff);
v[j] >>= 8;
}
}
}
return 0;
}
直接对照 encrypt()函数来写 decrypt()函数,然后修改一些问题。
#include <stdio.h>
#include <stdint.h>
void encrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1], sum = 0;
uint32_t delta = 0xd33b470;
for (int i = 0; i < 32; i++) {
sum += delta;
v0 += ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
v1 += ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
}
v[0] = v0;
v[1] = v1;
}
void decrypt(uint32_t* v, uint32_t* k) {
uint32_t v0 = v[0], v1 = v[1];
uint32_t delta = 0xd33b470;
uint32_t sum = delta * 32;
for (int i = 0; i < 32; i++) {
v1 -= ((v0 << 4) + k[2]) ^ (v0 + sum) ^ ((v0 >> 5) + k[3]);
v0 -= ((v1 << 4) + k[0]) ^ (v1 + sum) ^ ((v1 >> 5) + k[1]);
sum -= delta;
}
v[0] = v0;
v[1] = v1;
}
int main() {
uint32_t k[4] = { 1, 2, 3, 4 };
uint8_t input[33] = { 0x17, 0x65, 0x54, 0x89, 0xed, 0x65, 0x46, 0x32, 0x3d, 0x58, 0xa9, 0xfd, 0xe2, 0x5e,
0x61, 0x97, 0xe4, 0x60, 0xf1, 0x91, 0x73, 0xe9, 0xe9, 0xa2, 0x59, 0xcb, 0x9a, 0x99,
0xec, 0xb1, 0xe1, 0x7d };
//scanf("%32s", input);
for (int i = 0; i < 32; i += 8) {
uint32_t v[2] = { *(uint32_t*)&input[i], *(uint32_t*)&input[i + 4] };
decrypt(v, k);
for (int j = 0; j < 2; j++) {
for (int b = 0; b < 4; b++) {
printf("%c", (v[j] >> (8 * b)) & 0xff);
}
}
}
return 0;
}
//moectf{Th3_TEA_!S_s0_t4s7y~~!!!}
[HGAME 2023 week1]a_cup_of_tea
难道每一个 Buf2[i]都进行了TEA加密?
si128 = _mm_load_si128((const __m128i *)&xmmword_1400022B0);
英特尔的 SIMD指令集的一个SSE2指令,从内存中加载一个 128 位的整数向量到一个 __m128i 类型的寄存器中 .
先得到 key
ant='0x45678901345678902345678912345678'[2:]
print(ant)
print(len(ant))
key=[]
for i in range(0,len(ant),8):
key.append(int(ant[i:i+8],16))
print(key)