前言:熟悉的夜晚,记录一下Tea的加解密方法,由于时间原因,这个不会太探究原理,只作为一个案例来写,主要是根据xman的一个pwn题,魔改Tea
明文长度分组为64位(8字节),密钥长度为128位(16字节),明文和密钥进入32轮循环,得到最后的64位密文。其中magic number DELTA是由黄金分割点得到。 算法比较简单源码如下
#include<stdio.h> #define DELTA 0x9e3779b9 void tea_encrypt(unsigned int* v, unsigned int* key) { unsigned int l = v[0], r = v[1], sum = 0; for (size_t i = 0; i < 32; i++) { //进行32次迭代加密,Tea算法作者的建议迭代次数 l += (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]); sum += DELTA; //累加Delta的值 r += (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]); //利用多次双位移和异或将明文与密钥扩散混乱,并将两个明文互相加密 } v[0] = l; v[1] = r; } void tea_decrypt(unsigned int* v, unsigned int* key) { unsigned int l = v[0], r = v[1], sum = 0; sum = DELTA * 32; //32次迭代累加后delta的值 for (size_t i = 0; i < 32; i++) { r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]); sum -= DELTA; l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]); } v[0] = l; v[1] = r; } int main(int argc, char const *argv[]) { unsigned int key[4]={0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f}; unsigned int v1[2] = {0xaabbccdd,0x01234567}; tea_encrypt(v1,key); printf("tea_encrypt:%x %x\n",v1[0],v1[1]); tea_decrypt(v1,key); printf("tea_decrypt:%x %x\n",v1[0],v1[1]); return 0; }
xman 一个pwn题来具体简绍如何解密Tea
_BOOL8 __fastcall sub_11F0(_BYTE *a1) { sub_1035((unsigned int *)a1); return *a1 == 0x1E && a1[1] == 0x19 && a1[2] == 0x5D && a1[3] == 0x10 && a1[4] == 0xC8 && a1[5] == 0x70 && a1[6] == 0xE8 && a1[7] == 0x98; }
__int64 __fastcall sub_1035(unsigned int *a1) { __int64 result; // rax int i; // [rsp+1Ch] [rbp-3Ch] unsigned int v3; // [rsp+20h] [rbp-38h] unsigned int v4; // [rsp+24h] [rbp-34h] unsigned int v5; // [rsp+28h] [rbp-30h] int v6[6]; // [rsp+38h] [rbp-20h] unsigned __int64 v7; // [rsp+50h] [rbp-8h] v7 = __readfsqword(0x28u); v6[0] = 0x28371234; v6[1] = 0x19283543; v6[2] = 0x19384721; v6[3] = 0x98372612; v3 = *a1; v4 = a1[1]; v5 = 0; for ( i = 0; i <= 31; ++i ) { v3 += (((v4 >> 5) ^ (16 * v4)) + v4) ^ (v6[v5 & 3] + v5); v5 -= 0x61C88647; v4 += (((v3 >> 5) ^ (16 * v3)) + v3) ^ (v6[(v5 >> 11) & 3] + v5); } *a1 = v3; result = v4; a1[1] = v4; return result; }
解密exp.c:
#include <stdio.h> #include <stdlib.h> unsigned int key[4]={0x28371234,0x19283543,0x19384721,0x98372612}; unsigned int firstChunk=0x105d191e; unsigned int secondChunk=0x98e870c8; //倒叙就可以拉 //unsigned int firstChunk=0x9a3df895; //unsigned int secondChunk=0xb2a32f77; int main() { unsigned int sum = 0; unsigned int v0 = firstChunk; unsigned int v1 = secondChunk; unsigned int delta = 0x14872109; //0x61C88647 for (int j=0;j<=16;j++) { sum += delta; } for (int i = 0; i <= 16; i++) { v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); sum -= delta; v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]); } printf("0x%x\n",v0); printf("0x%x\n",v1); } //v4 += (((v3 >> 5) ^ (16 * v3)) + v3) ^ (v6[(v5 >> 11) & 3] + v5); v4 = a1[1]; //v4 += (((v3 >> 5) ^ (16 * v3)) + v3) ^ (v6[(v5 >> 11) & 3] + v5);
Tea好奇妙,爬