Bootstrap

基于2019RedHat(红帽杯)-xx题目学习XXTEA解密

关于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打开
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

总结流程

  1. 输入flag,取前四个字符作为密钥进行xxtea加密
  2. 然后进行置换混淆
  3. 在进行3个一组的异或
  4. 最后和密文比较

上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'
;