⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 qq_tea.cpp

📁 QQ的TEA加密算法,有要的可以下下来玩玩!
💻 CPP
字号:
/**********************************************************   TEA - Tiny Encryption Algorithm   Feistel cipher by David Wheeler & Roger M. Needham   (extended version) **********************************************************/#include "tea.h"


//bool header = true;//是否加密头


/**********************************************************   Input values: 	k[4]	128-bit key			v[2]    64-bit plaintext block   Output values:	v[2]    64-bit ciphertext block  **********************************************************/void enc_block(dword *v, dword *k, dword *out) {	dword y=v[0], z=v[1];
	__asm
	{
		mov eax, dword ptr[ebp - 4]
			bswap eax
			mov y, eax
			
			mov eax, dword ptr[ebp -8]
			bswap eax
			mov z, eax
	}
	dword ROUND = 0x10,sum=0;
	while(ROUND--)
	{
		sum+=DELTA;
		y+=(((z>>5) + k[1])^((z<<4) + k[0])) ^ (z + sum);
		z+=(((y>>5) + k[3])^((y<<4) + k[2])) ^ (y + sum);			
		
	}
	__asm//转换字节位置
	{
		mov eax,dword ptr[ebp - 4]
			bswap eax
			mov y, eax
			mov eax,dword ptr [ebp - 8]
			bswap eax
			mov z, eax
	}
	 out[0] = y; out[1] = z;}void dec_block(dword *v, dword *k, dword *out) {
	dword y = v[0], z = v[1];
	__asm
	{
		mov eax, dword ptr[ebp - 4]
		bswap eax
		mov dword ptr[ebp - 4], eax

		mov eax, dword ptr[ebp - 8]
		bswap eax
		mov dword ptr[ebp - 8], eax
	}
	dword ROUND = 0x10, sum = 0;
	sum=DELTA*ROUND;
	while (ROUND--)
	{
		z-=((y>>5) + k[3])^((y<<4) + k[2]) ^ (y + sum);
		y-=(((z>>5) + k[1])^((z<<4) + k[0])) ^ (z + sum);
	    sum-=DELTA;
	}
	__asm
	{
		mov eax, dword ptr[ebp - 4]
		bswap eax
		mov dword ptr[ebp - 4], eax
		
		mov eax, dword ptr[ebp - 8]
		bswap eax
		mov dword ptr[ebp - 8], eax
	}
	out[0] = y; out[1] = z;}


/************************************************************************/
/* QQ的TEA加密算法														*/
/* pPlainData (global)明文数据											*/
/* len  明文长度(local)												*/
/* pKey 密钥(local)														*/
/* pCryptData  (global)加密后的数据                                     */
/************************************************************************/
void encrypt(BYTE *pPlainData, dword len, dword *pKey, BYTE *&pCryptData)
{
	dword codelen;//密文长度
	BYTE *pre_crypt, *pcrypt;	//当前加密的明文和密文地址
	BYTE plain[8], pre_plain[8];
	bool header = true;
	//计算头部填充字节数;
	int pos = (len + 0x0A) %8;
	if (pos != 0)
	{
		pos = 8 - pos;
	};
	//计算输出的密文长度
	codelen = len + pos + 0x0A;
	pCryptData = (BYTE*)malloc(codelen);
	memset(pCryptData, 0, codelen);
	pcrypt = pCryptData;
	
	
	srand(time(NULL));
	//把pos(明文位置)放到填充的第一个字节里面
	plain[0] = rand()&0xF8 | pos;
	
	//|__ __ __ __ |__ __ __ __|
	//  |       pos
	//plain[0] 里面有明文位置;

	for (int i = 1; i <= pos; i++ )//填充plain[1]--plain[pos]之间的内容
	{
		plain[i] = rand()&0xFF;
	}
	pos++;
	//初始化上次明文内容
	for (i = 0; i < 8; i++)
	{//加密第一个64位,前次加密内容当然为0x00000000, 0x00000000
		pre_plain[i] = 0x00;
	}
	// 继续填充2个字节的随机数,这个过程中如果满了8字节就加密之
	for (int padding = 0; padding < 2; padding++)
	{
		if (pos < 8)
		{
			//填充随机数
			plain[pos] = rand()&0xFF;
			++pos;
		}
		
		if (pos == 8)//满8个就加密
		{
			//encrypt8bytes(plain_index, pKey, crypt_index);
			if (header)//------------------当前明文异或上次密文------------------
			{
				for (i = 0; i < 8; i++)
				{
					plain[i] ^= pre_plain[i];	
				}
				header = false;	
			}
			else
			{
				for (i = 0; i < 8; i++)
				{
					plain[i] ^= pre_crypt[i];
				}	
			}//-----------------异或完了加密之-----------------------------
			enc_block((dword*)plain, (dword*)pKey, (dword*)pcrypt);

			for (i = 0; i < 8; i++)//当前密文 = 当前密文 ^ 上次明文
			{
				pcrypt[i] ^= pre_plain[i];
			}
			memcpy(pre_plain, plain, 8);
			pos = 0;
		}
	}
	
	unsigned long offset = 0;
	//如果没填满,就开始填明文
	while (len > 0)
	{
		if (pos < 8)
		{
			plain[pos++] = pPlainData[offset++];
			len --;
		}
		if (pos == 8)
		{
//			encrypt8bytes(pKey);
			if (header)//------------------当前明文异或上次密文------------------
			{
				for (i = 0; i < 8; i++)
				{
					plain[i] ^= pre_plain[i];	
				}
				header = false;	
			}
			else
			{			
				pre_crypt = pcrypt;
				pcrypt += 8;
				for (i = 0; i < 8; i++)
				{
					plain[i] ^= pre_crypt[i];
				}	
			}//-----------------异或完了加密之-----------------------------

// 			for (i = 0; i < 8; i++)
// 			{
// 				plain[i] ^= pre_crypt[i];
// 			}	
			//-----------------异或完了加密之-----------------------------
			enc_block((dword*)plain, (dword*)pKey, (dword*)pcrypt);
			
			for (i = 0; i < 8; i++)//当前密文 = 当前密文 ^ 上次明文
			{
				pcrypt[i] ^= pre_plain[i];
			}
			memcpy(pre_plain, plain, 8);
			pos = 0;
		}
			
	}
	//如果最后不够8字节了,用零填满8个字节
	padding = 1;
	while (padding <= 7)
	{
		if (pos < 8)
		{
			plain[pos++] = 0x00;
			padding ++;
		}
		if (pos == 8)
		{
//			encrypt8bytes(pKey);
			pre_crypt = pcrypt;
			pcrypt += 8;
			for (i = 0; i < 8; i++)
			{
				plain[i] ^= pre_crypt[i];
			}	
			//-----------------异或完了加密之-----------------------------
			enc_block((dword*)plain, (dword*)pKey, (dword*)pcrypt);
			
			for (i = 0; i < 8; i++)//当前密文 = 当前密文 ^ 上次明文
			{
				pcrypt[i] ^= pre_plain[i];
			}
		}
	}
}


/************************************************************************/
/* QQ的TEA解密算法														*/
/* pCrypeData (global)密文数据											*/
/* len  密文长度(local)												*/
/* pKey 密钥(local)														*/
/* pPlainData  (global)解密后的数据                                     */
/************************************************************************/
void decrypt(BYTE *pCryptData, dword len, BYTE *pKey, BYTE *&pPlainData)
{
	BYTE plain[8];//用来存放解密后的值
	BYTE precrypt[8];//用来存放上次解密的密文
	BYTE *pcrypt, *pre_crypt;
	BYTE *pre_plain,*pplain;//上次解密出的明文
	pcrypt = pCryptData;
	bool header = true;
	//检查密文长度,是否正确
	if (0 != len % 8 | len < 16)
	{
		printf("length error!");
	}

	dec_block((dword*)pCryptData, (dword*)pKey, (dword*)plain);
	//明文长度plain_len
	dword pos = plain[0] &0x07;
	dword plain_len = len - pos - 0x0A;
	pPlainData = new BYTE[plain_len];
	pplain = pPlainData;
	if (plain_len < 0)
	{
		printf("length error!");
	}

	// 这个是临时的preCrypt,和加密时第一个8字节块没有prePlain一样
	for (int i = 0; i < 8; i++)
	{
		precrypt[i] = 0x00;
	}
	pos ++;

	int padding = 1;
	while (padding <= 2)
	{
		if (pos < 8)//证明头字节中有明文信息
		{
			pos ++;
			padding ++;
		}
		if (pos == 8)//证明头8字节都是无用的填充
		{
			//解密8字节
			//decrypt8Bytes(inData, offset, len)
			pre_crypt = pcrypt; pcrypt +=8;
			for ( i = 0; i< 8; i++)
			{
				plain[i] ^= pcrypt[i];//上次明文 ^ 此次密文
			}
			dec_block((dword*)plain,(dword*)pKey,(dword*)plain);
			pos = 0;
		}
	}
	dword offset = 0;
	while (plain_len != 0)
	{
		if (pos < 8)//证明
		{
			if (header)
			{
				pPlainData[offset] = plain[pos] ^ precrypt[pos];
			}
			else
			{//保存使用此次明文^上次密文
				pPlainData[offset] = plain[pos] ^ pre_crypt[pos];	
			}
			plain_len --;
			pos++;
			offset ++;
		}
		if (pos == 8)
		{
			header = false;
			pre_crypt = pcrypt; pcrypt +=8;
			for ( i = 0; i< 8; i++)
			{
				plain[i] ^= pcrypt[i];//上次明文 ^ 此次密文
			}
			dec_block((dword*)plain,(dword*)pKey,(dword*)plain);
			pos = 0;
		}
	}

	for (padding = 1; padding <= 7; padding++)
	{
		if (pos < 8)
		{
			if ( (plain[pos] ^ pre_crypt[pos]) != 0)
			{
				printf("decrypt error!");
			}
			pos ++;
		}
		if (pos == 8)
		{
			pre_crypt = pcrypt; pcrypt +=8;
			if (pcrypt - pCryptData >= len)
			{
				return;
			}
			for ( i = 0; i< 8; i++)
			{
				plain[i] ^= pcrypt[i];//上次明文 ^ 此次密文
			}
			dec_block((dword*)plain,(dword*)pKey,(dword*)plain);
			pos = 0;
		}
	}

}


void main()
{
//	volatile int m = 0x100;
//	m = m << 2;
	dword key[4] = {0x55486B40,0x12B62930,0x05D12B06,0x51B4189D};
	dword v[] = {0xab050402, 0x12121212, 0x23232323,0xcdef2376,0x12345678};
	BYTE *pcrypt;
	dword len = sizeof(v);
	encrypt((BYTE*)v, len, key, pcrypt);
	int pos = (len + 0x0A) %8;
	if (pos != 0)
	{
		pos = 8 - pos;
	};
	//计算输出的密文长度
	int codelen = len + pos + 0x0A;
	printf("密文内容:\n");
	for (int i = 0;i < codelen; i++)
	{	
		printf("%02X ", pcrypt[i]);
		if ( 0 == (i+1)%8)
		{
			printf("\n");
		}
		
	}
	printf("\n");

	BYTE *plain;
	decrypt((BYTE*)pcrypt, codelen, (BYTE*)key, plain);
	printf("解密后内容:\n");
	for (i = 0; i < len; i++)
	{
		printf("%02X ", plain[i]);
		if ((i+1)%8 == 0)
		{
			printf("\n");
		}
	}
	printf("\n\n\n\n\n\n");
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -