声明
本文属于OneTS安全团队成员flatcc的原创文章,转载请声明出处!本文章仅用于学习交流使用,因利用此文信息而造成的任何直接或间接的后果及损失,均由使用者本人负责,OneTS安全团队及文章作者不为此承担任何责任。
TEA 分组加密算法
TEA
TEA是Tiny Encryption Aigorithm 的缩写,以加密解密速度快,实现简单著称。
TEA算法每一次可以操作64bit(8byte),采用128bit(16byte)作为key,算法采用选代的形式,推荐的迭代轮数是64轮,最少32轮,(可改变)。
TEA系列算法中均使用了一个DELTA常敌,但DELTA的值对算法并无什么影响,只是为了避免不良的取值,推荐DELTA的值取为黄金分割数(5V-2)/2与232的乘积,取整后的十六进制值为0x9e3779B9(也可以改变),用于保证每一轮加密都不相同。
为解决TEA算法密钥表攻击的问题,TEA算法先后经历了几次改进,从 XTEA 到 BLOCK TEA、直至最新的 XXTEAX。
XTEA:使用与TEA相同的简单运算,但四个子密钥采取不正规的方式进行混合以阻止密钥表攻击。
Block TEA 算法可以对32位的任意整数倍长度的变量块进行加解密的操作,该算法将XTEA轮循函数依次应用干块中的每个字,井且将它附加于被应用字的邻字。
XXTEA使用跟BlockTEA相似的结构,但在处理块中每个字时利用了相邻字,且用拥有两个输入量的MX函数代善了XTEA 轮询函数。上面提到的相邻字其实就是数组中相邻的项。
只要会处理 TEA,XTEA和XXTEA也是同理
代码案例及原理(个人小结)
TEA算法是一种分组加密算法,它的实现非常简单,通常只需要很精短的几行代码。
该算法分组长度为64位,密钥长度为128位,其作者推荐使用32次循环加密,即64轮。
识别该算法的关键点应该在于,第一是加密循环次数一般为32次,其次识别delta中的压缩常数,该常数由黄金分割点得到。
🔷C代码 加解密函数注意事项: ●输入:数据是8个字节,key是32个字节 ●输出:在原数据地址空间输出,8个字节
/*********************************************************/
/* 描述:C版本TEA加密解密示例
/* 日期:2021/8/10
/* 作者:flatcc
/* 来源:https://www.cnblogs.com/LyShark/p/13407677.html
/*********************************************************/
#include <stdio.h>
#include <string.h>
void encrypt(unsigned int *A, unsigned int *B) {
int j;
unsigned int v0 = A[0], v1 = A[1], sum = 0, delta = 0x9E3779B9;
for (j = 0; j < 32; j++) {
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + B[sum & 3]);
sum += delta;
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + B[(sum >> 11) & 3]);
}
A[0] = v0;
A[1] = v1;
}
void decrypt(unsigned int *A, unsigned int *B) {
int j;
unsigned int v0 = A[0], v1 = A[1], delta = 0x9E3779B9, sum = delta * 32;
for (j = 0; j < 32; j++) {
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + B[(sum >> 11) & 3]);
sum -= delta;
v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + B[sum & 3]);
}
A[0] = v0;
A[1] = v1;
}
int main(int argc, char *argv[])
{
unsigned int data[2] = {0}; //初始化栈空间为0
unsigned int key[4] = { 1, 2, 3, 4 };
//这里得小于8个字节
memcpy(data, "flatcc", 8);
// 加密后输出
encrypt(data, key);
for (int i = 0; i < 2; i++)
printf("加密后的数据: %X ", data[i]);
printf("\n");
// 解密后输出
data[0] = 0xC97F0712;
data[1] = 0x27201662;
decrypt(data, key);
printf("解密后的数据: %s\n", data);
return 0;
}
例题:
宁盾杯2021题目justRE
记得关注我们,了解更多技术知识!