关于XXTEA解密的理解(题目加解题做法)
了解一下tea和xtea 与 xxtea的区别
tea和xtea是块密码算法,通常用于对64位(两个32位数据块)进行加密。每次操作,它们处理两个数据块,因此一次性可以加密两个32位的数据。TEA和XTEA的设计是为了简单、轻量级,特别适用于嵌入式系统和对性能要求不太严格的场景。它们的特点是加密和解密的操作都是块操作,而且轮数相对较少。
而相比于TEA和XTEA,XXTEA(eXtended eXtended Tiny Encryption Algorithm)是一种更灵活的块密码算法,允许一次性加密多个数据块。XXTEA的设计目标之一是提供更大的块大小和更高的灵活性。XXTEA是一种迭代式加密算法,通常用于加密不定长度的二进制数据。其设计允许处理可变长度的数据块,因此你可以一次性加密多个数据块。这对于某些应用场景可能是有用的,例如加密长文本或二进制数据流。
基于c的加解密代码如下
#include<stdio.h>
#include<stdint.h>
void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[4]){
unsigned int i;
uint32_t v0=v[0],v1=v[1],sum=0,delta=0x9E3779B9;
for(i=0;i<num_rounds;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;
}
void decipher(unsigned int num_rounds,uint32_t v[2],uint32_t const key[4]){
unsigned int i;
uint32_t v0=v[0],v1=v[1],delta=0x9E3779B9,sum=delta*num_rounds;
for(i=0;i<num_rounds;i++){
v1-=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);
sum-=delta;
v0-=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);
}
v[0]=v0;v[1]=v1;
}
int main(){
uint32_t v[2]={1,2};
uint32_t const k[4]={2,2,3,4};
unsigned int r=32; //这里是加密轮数,自己设置
printf("加密前原始数据:%u %u\n",v[0],v[1]);
encipher(r,v,k);
printf("加密后原始数据:%u %u\n",v[0],v[1]);
decipher(r,v,k);
printf("解密后原始数据:%u %u\n",v[0],v[1]);
return 0;
}
基于python的加解密代码如下
from ctypes 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):
v0.value+=(((v1.value<<4)^(v1.value>>5))+v1.value)^(sum1.value+k[sum1.value&3])
sum1.value+=delta
v1.value+=(((v0.value<<4)^(v0.value>>5))+v0.value)^(sum1.value+k[(sum1.value>>11)&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*32)
for i in range(32):
v1.value-=(((v0.value<<4)^(v0.value>>5))+v0.value)^(sum1.value+k[(sum1.value>>11)&3])
sum1.value-=delta
v0.value-=(((v1.value<<4)^(v1.value>>5))+v1.value)^(sum1.value+k[sum1.value&3])
return v0.value,v1.value
if __name__=='__main__':
a=[1,2]
k=[2,2,3,4]
print("加密前数据:",a)
res=encrypt(a,k)
print("加密后的数据:",res)
res=decrypt(res,k)
print("解密后数据:",res)
看一道buu上的一道例题 (2019RedHat(红帽杯)-xx)
ida打开
总结流程
- 输入flag,取前四个字符作为密钥进行xxtea加密
- 然后进行置换混淆
- 在进行3个一组的异或
- 最后和密文比较
上exp: (代码可能写的有点杂乱,本人懒得优化了0^0)
data = [0xCE, 0xBC, 0x40, 0x6B, 0x7C, 0x3A, 0x95, 0xC0, 0xEF, 0x9B,
0x20, 0x20, 0x91, 0xF7, 0x02, 0x35, 0x23, 0x18, 0x02, 0xC8,
0xE7, 0x56, 0x56, 0xFA ] #注意小端序储存
dec = ''
for i in range(7,-1,-1):
enc = ''
for j in range(3):
temp = data[i*3 + j]
for n in range(i):
temp ^= data[n]
enc += chr(temp)
dec = enc + dec #注意小端序储存
num = [2,0,3,1,6,4,7,5,10,8,11,9,14,12,15,13,18,16,19,17,22,20,23,21]
enc = [0] * 24
encflag = []
for i in range(24):
enc[num[i]] = dec[i]
for j in range(len(enc)):
encflag.append(ord(enc[j]))
print(encflag)
t = [int.from_bytes(encflag[i:i+4],byteorder='little') for i in range(0,len(encflag),4)]#导出加密的数据,并用小端序来表示
# print(t)
v = []
for i in t:
v.append(hex(i))
# print(v)
temp = [0x40cea5bc, 0xe7b2b2f4, 0x129d12a9, 0x5bc810ae, 0x1d06d73d, 0xdcf870dc]
flag = b''
from ctypes import *
import libnum
def MX(z, y, sum1, k, p, e):
return c_uint32(((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))
def btea(v,k,n,delta):
if n>1:
sum1=c_uint32(0)
z=c_uint32(v[n-1])
rounds=6+52//n
e=c_uint32(0)
while rounds>0:
sum1.value+=delta
e.value=((sum1.value>>2)&3) #e都要32位哦
for p in range(n-1):
y=c_uint32(v[p+1])
#v[p]=c_uint32(v[p]+c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))).value).value
v[p] = c_uint32(v[p] + MX(z,y,sum1,k,p,e).value).value
z.value=v[p]
y=c_uint32(v[0])
#v[n-1]=c_uint32(v[n-1]+c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[((n-1)&3)^e.value]^z.value)))).value).value #这里tmd传入的是k[((n-1)&3)啊我草,找了半天!!!
v[n-1] = c_uint32(v[n-1] + MX(z,y,sum1,k,n-1,e).value).value
z.value=v[n-1]
rounds-=1
else:
sum1=c_uint32(0)
n=-n
rounds=6+52//n
sum1.value=rounds*delta
y=c_uint32(v[0])
e=c_uint32(0)
while rounds>0:
e.value=((sum1.value>>2)&3) #e都要32位哦
for p in range(n-1, 0, -1):
z=c_uint32(v[p-1])
#y[p]=c_uint32(v[p]-c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[(p&3)^e.value]^z.value)))).value).value
v[p] = c_uint32(v[p] - MX(z,y,sum1,k,p,e).value).value
y.value=v[p]
z=c_uint32(v[n-1])
#v[n-1]=c_uint32(v[n-1]-c_uint32((((z.value>>5^y.value<<2)+(y.value>>3^z.value<<4))^((sum1.value^y.value)+(k[((n-1)&3)^e.value]^z.value)))).value).value
v[0] = c_uint32(v[0] - MX(z,y,sum1,k,0,e).value).value
y.value=v[0]
sum1.value-=delta
rounds-=1
return v
key = ''.join(format(ord(char), 'x') for char in reversed(['f', 'l', 'a', 'g']))#导出密钥,将其转换为十六进制并用小端序来表示
# print(key)
k = [0x67616c66,0x0,0x0,0x0] #密钥为4个32位的数,1个字符8bit,4个字符为32bit,还差3个32bit的数
if __name__ == '__main__':
a = temp
k = [0x67616c66,0x0,0x0,0x0]
delta = 0x9e3779b9
n = 6
res = btea(a,k,-n,delta)
for i in res:
flag += libnum.n2s(i)[::-1]
print("解密后数据:",flag)
#解密后数据: b'flag{CXX_and_++tea}\x13'