XTEA
XTEA加密算法
本篇文章面向有TEA基础的读者,如果你不了解TEA,也可以从我的博客中学习TEA加密算法
XTEA 与 TEA 的关系
XTEA(eXtended Tiny Encryption Algorithm)是在 TEA(Tiny Encryption Algorithm)的基础上改进得到的一种对称分组密码算法,两者具有相同的整体框架,均采用 64 位分组、128 位密钥,并使用 Feistel 网络结构,通过加法(Addition)、异或(XOR)和移位(Shift)等简单运算完成加解密。
代码实现
#include <cstdint>
void xtea_encrypt(uint32_t v[2], const uint32_t key[4])
{
uint32_t v0 = v[0], v1 = v[1];
uint32_t sum = 0;
const uint32_t delta = 0x9E3779B9;
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]);
}
v[0] = v0;
v[1] = v1;
}
我们直接通过阅读代码来找到在TEA上进行改动的痕迹
其中改动最明显的莫过于
(sum + key[sum & 3]);
(sum + key[(sum >> 11) & 3])
key的索引受到了sum的影响,依旧是单元运算异或
然后是sum在轮运算中的处理,先处理完一轮后再对sum进行累加运算,在这里逆向的顺序就发生了改变
可以发现整体的改动不算太大,我们直接结合题目进行逆向工程的教学
逆向工程部分
题目名称:[Harukaze]NSSCTF2025入门题目-XTea
题目来源:NSSCTF
下载题目附件,拖入IDA

直接查看check逻辑

看看xtea_encrypt函数

XTEA加密,略微进行了修改
值得注意的是,这里的sum并不是真的-= 1640531527
这里利用了无符号整数的mod 2^32运算
反编译得到的是
sum -= 1640531527;
其中
1640531527 = 0x61C88647
与标志delta值的关系
0x9E3779B9 + 0x61C88647 = 0x100000000 = 2^32
因此有0x61C88647≡−0x9E3779B9(mod232)
也就是说
sum -= 0x61C88647;
在uint32_t下,等价于
sum += 0x9E3779B9;
这与uint32_t类型整数的运算息息相关
而其他的代码片段,多是确保校验位置,以及校验数据的正确性,不影响算法,我们查看密文和key后就能写出解密脚本

以上密钥部分,记得取128位,16字节数据即可
以下密文部分,ciphertext数组,刚好是8字节的整数倍

完整EXP
#include <iostream>
#include <cstdint>
#include <windows.h>
using namespace std;
void decrypt(uint32_t *v,uint32_t *key)
{
uint32_t v0=*v;
uint32_t v1=v[1];
uint32_t sum=0;
uint32_t delta=0x414554;
for(int i=0;i<32;i++)
{
sum+=delta;
};
for(int i=0;i<32;i++)
{
v1-= (v0 + sum) ^ (16 * v0 + key[2]) ^ ((v0 >> 5) + key[3]);
v0 -= (v1 + sum) ^ (16 * v1 + *key) ^ ((v1 >> 5) + key[1]);
sum -= delta;
}
v[0]=v0; v[1]=v1;
}
int main()
{
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);
uint8_t enc[] =
{
0xE4, 0x6E, 0x00, 0xF0, 0x91, 0x73, 0x9A, 0xBE, 0xCA, 0xF1,
0x2A, 0x60, 0x0E, 0x8F, 0x74, 0x83, 0xE0, 0x8E, 0x6C, 0x34,
0xD7, 0x99, 0xDE, 0x36, 0x8B, 0x86, 0xC4, 0x90, 0xC2, 0x0B,
0xC4, 0x59
};
uint8_t key[] =
{
0xEF, 0xBE, 0xAD, 0xDE, 0x0D, 0xF0, 0xAD, 0xBA, 0xDE, 0xC0,
0xAD, 0xDE, 0xCC, 0x10, 0xAD, 0xDE
};
for (int i = 0; i < sizeof(enc); i+=8)
{
decrypt((uint32_t*)(enc + i), (uint32_t*)key);
}
cout<<(char*)enc;
system("pause");
}
结果就请自己运行试试看啦,如果你觉得本篇文章对你有帮助不妨点个赞,如果觉得存在问题欢迎在评论区以及私信作者

浙公网安备 33010602011771号