开始tea加密的学习
tea 加密: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <stdio.h> #include <stdint.h> void encrypt (uint32_t * v, uint32_t * k) { uint32_t v0 = v[0 ], v1 = v[1 ], sum = 0 , i; uint32_t delta = 0x9e3779b9 ; uint32_t k0 = k[0 ], k1 = k[1 ], k2 = k[2 ], k3 = k[3 ]; for (i = 0 ; i < 32 ; i++) { sum += delta; v0 += ((v1 << 4 ) + k0) ^ (v1 + sum) ^ ((v1 >> 5 ) + k1); v1 += ((v0 << 4 ) + k2) ^ (v0 + sum) ^ ((v0 >> 5 ) + k3); } v[0 ] = v0; v[1 ] = v1; } int main () { uint32_t plaintext[8 ] = { 0x67616C66 , 0x3332317B , 0x37363534 , 0x30303938 , 0x34333231 , 0x38373635 , 0x32313039 , 0x7D353433 }; uint32_t key[4 ] = { 0x34333231 , 0x38373635 , 0x32313039 , 0x36353433 }; printf ("原始明文(小端序十六进制):\n" ); for (int i = 0 ; i < 8 ; i++) { printf ("0x%08X " , plaintext[i]); if (i % 2 == 1 ) printf ("\n" ); } for (int i = 0 ; i < 8 ; i += 2 ) { uint32_t v[2 ] = { plaintext[i], plaintext[i + 1 ] }; encrypt(v, key); plaintext[i] = v[0 ]; plaintext[i + 1 ] = v[1 ]; } printf ("\n加密后的密文(小端序十六进制):\n" ); for (int i = 0 ; i < 8 ; i++) { printf ("0x%08X " , plaintext[i]); if (i % 2 == 1 ) printf ("\n" ); } return 0 ; }
python和c与语言在tea加密的时候会发现有时候会不一样,其中有可能是小端序储存的问题。
解密 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 #include <stdio.h> #include <stdint.h> void decrypt (uint32_t * v, uint32_t * k) { uint32_t v0 = v[0 ], v1 = v[1 ], sum = 0xC6EF3720 , i; uint32_t delta = 0x9e3779b9 ; uint32_t k0 = k[0 ], k1 = k[1 ], k2 = k[2 ], k3 = k[3 ]; for (i = 0 ; i < 32 ; i++) { v1 -= ((v0 << 4 ) + k2) ^ (v0 + sum) ^ ((v0 >> 5 ) + k3); v0 -= ((v1 << 4 ) + k0) ^ (v1 + sum) ^ ((v1 >> 5 ) + k1); sum -= delta; } v[0 ] = v0; v[1 ] = v1; } int main () { uint32_t k[4 ] = {0x34333231 , 0x38373635 , 0x32313039 , 0x36353433 }; uint32_t blocks[4 ][2 ] = { {0x4438A9E2 , 0x39D00322 }, {0x55564858 , 0x0414AC05 }, {0x4D66EF71 , 0x5ABD1754 }, {0x94554B4A , 0x8F3245C0 } }; for (int i = 0 ; i < 4 ; i++) { uint32_t v[2 ] = {blocks[i][0 ], blocks[i][1 ]}; decrypt(v, k); uint8_t *bytes = (uint8_t *)v; for (int j = 0 ; j < 8 ; j++) { printf ("%c" , bytes[j]); } } printf ("\n" ); return 0 ; }
介绍 TEA(Tiny Encryption Algorithm)是一种分组密码算法,由David Wheeler和Roger Needham于1994年提出。它采用64位数据块和128位
密钥,具有简单、高效的特点。算法使用32轮循环的Feistel结构,每轮操作包括移位、异或和加法
最常魔改点 delta = 0x9e3779b9(标准) 这里经常会被换成别的数据
在反汇编中x-=0x61c88647和x+=0x9e3779b9,这两个值是等价的。
进行32轮循环,每轮执行以下操作:
1 2 3 sum += delta; v0 += ((v1 << 4 ) + k0) ^ (v1 + sum) ^ ((v1 >> 5 ) + k1); v1 += ((v0 << 4 ) + k2) ^ (v0 + sum) ^ ((v0 >> 5 ) + k3);
解密的换就反过来进行32次就可以了
1 2 3 v1 -= ((v0 << 4 ) + k2) ^ (v0 + sum) ^ ((v0 >> 5 ) + k3); v0 -= ((v1 << 4 ) + k0) ^ (v1 + sum) ^ ((v1 >> 5 ) + k1); sum -= delta;
xtea 加密 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <stdio.h> #include <stdint.h> #include <string.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; } int main () { uint32_t plaintext[8 ] = { 0x67616C66 , 0x3332317B , 0x37363534 , 0x30303938 , 0x34333231 , 0x38373635 , 0x32313039 , 0x7D353433 }; uint32_t const key[4 ] = { 0x34333231 , 0x38373635 , 0x32313039 , 0x36353433 }; unsigned int num_rounds = 32 ; printf ("原始明文:\n" ); for (int i = 0 ; i < 8 ; i++) { printf ("%08X " , plaintext[i]); if (i % 2 == 1 ) printf ("\n" ); } for (int i = 0 ; i < 8 ; i += 2 ) { uint32_t block[2 ] = { plaintext[i], plaintext[i + 1 ] }; encipher(num_rounds, block, key); plaintext[i] = block[0 ]; plaintext[i + 1 ] = block[1 ]; } printf ("\n加密后的密文:\n" ); for (int i = 0 ; i < 8 ; i++) { printf ("%08X " , plaintext[i]); if (i % 2 == 1 ) printf ("\n" ); } return 0 ; }
解密 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 #include <stdio.h> #include <stdint.h> 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 const key[4 ] = { 0x34333231 , 0x38373635 , 0x32313039 , 0x36353433 }; unsigned int r = 32 ; uint32_t ciphertext[4 ][2 ] = { {0x37DB3CE9 , 0x6C07F159 }, {0xE1893135 , 0x57978EA8 }, {0xB159F7E6 , 0x439F8389 }, {0x988499C3 , 0x9765BBF9 } }; printf ("解密后的数据:\n" ); for (int i = 0 ; i < 4 ; i++) { uint32_t v[2 ] = { ciphertext[i][0 ], ciphertext[i][1 ] }; decipher(r, v, key); printf ("组 %d: 0x%08X 0x%08X\n" , i + 1 , v[0 ], v[1 ]); unsigned char * bytes = (unsigned char *)v; printf (" 作为字节序列: " ); for (int j = 0 ; j < 8 ; j++) { printf ("%02X " , bytes[j]); } printf ("\n 可能作为字符串: " ); for (int j = 0 ; j < 8 ; j++) { if (bytes[j] >= 32 && bytes[j] <= 126 ) { printf ("%c" , bytes[j]); } else { printf ("." ); } } printf ("\n\n" ); } return 0 ; }
介绍 XTEA(eXtended TEA)是 TEA 算法的改进版,由 David Wheeler 和 Roger Needham 于 1997 年提出,主要修复了 TEA 的相关密钥攻击漏洞,以 64 位为数据块、128 位为密钥,通过 32 轮包含加 / 减、循环移位和异或的操作实现加密解密,因轻量易实现、对资源需求低,常用于嵌入式设备等场景。
最常魔改点 delta
是魔数0x9E3779B9 这个数据经常被换。
加密核心
1 2 3 4 5 6 7 8 9 10 11 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; }
解密的换就反过来进行
1 2 3 4 5 6 7 8 9 10 11 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; }
xxtea 加密 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 #include <stdio.h> #include <stdint.h> #define DELTA 0x9e3779b9 #define MX (((z >> 5 ^ y << 2) + (y > > 3 ^ z << 4)) ^ ((sum ^ y) + (key[(p & 3) ^ e] ^ z))) void btea (uint32_t * v, int n, uint32_t const key[4 ]) { uint32_t y, z, sum; unsigned p, rounds, e; if (n > 1 ) { rounds = 6 + 52 / n; sum = 0 ; z = v[n - 1 ]; do { sum += DELTA; e = (sum >> 2 ) & 3 ; for (p = 0 ; p < n - 1 ; p++) { y = v[p + 1 ]; z = v[p] += MX; } y = v[0 ]; z = v[n - 1 ] += MX; } while (--rounds); } } int main () { uint32_t v[8 ] = { 0x67616C66 , 0x3332317B , 0x37363534 , 0x30303938 , 0x34333231 , 0x38373635 , 0x32313039 , 0x7D353433 }; uint32_t const k[4 ] = { 0x34333231 , 0x38373635 , 0x32313039 , 0x36353433 }; int n = 8 ; printf ("原始明文(小端序十六进制):\n" ); for (int i = 0 ; i < n; i++) { printf ("0x%08X " , v[i]); } printf ("\n" ); btea(v, n, k); printf ("加密后的数据(十六进制):\n" ); for (int i = 0 ; i < n; i++) { printf ("0x%08X " , v[i]); } printf ("\n" ); return 0 ; }
解密 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 #include <stdio.h> #include <stdint.h> #define DELTA 0x9e3779b9 #define MX (((z>>5^y<<2) + (y> >3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z))) void btea (uint32_t * v, int n, uint32_t const key[4 ]) { uint32_t y, z, sum; unsigned p, rounds, e; if (n > 1 ) { rounds = 6 + 52 / n; sum = 0 ; z = v[n - 1 ]; do { sum += DELTA; e = (sum >> 2 ) & 3 ; for (p = 0 ; p < n - 1 ; p++) { y = v[p + 1 ]; z = v[p] += MX; } y = v[0 ]; z = v[n - 1 ] += MX; } while (--rounds); } else if (n < -1 ) { n = -n; rounds = 6 + 52 / n; sum = rounds * DELTA; y = v[0 ]; do { e = (sum >> 2 ) & 3 ; for (p = n - 1 ; p > 0 ; p--) { z = v[p - 1 ]; y = v[p] -= MX; } z = v[n - 1 ]; y = v[0 ] -= MX; sum -= DELTA; } while (--rounds); } } int main () { uint32_t v[8 ] = { 0x3E95DFCB , 0x608F99DA , 0x40ABC551 , 0x941490C5 , 0x7985C1B9 , 0x20FC9B0A , 0x23C095EB , 0x62EFB4EE }; uint32_t const k[4 ] = { 0x34333231 , 0x38373635 , 0x32313039 , 0x36353433 }; int n = 8 ; printf ("密文数据:\n" ); for (int i = 0 ; i < n; i++) { printf ("0x%08X " , v[i]); if ((i + 1 ) % 4 == 0 ) printf ("\n" ); } btea(v, -n, k); printf ("\n解密后的数据:\n" ); for (int i = 0 ; i < n; i++) { printf ("0x%08X " , v[i]); if ((i + 1 ) % 4 == 0 ) printf ("\n" ); } printf ("\n解密后的字符串:\n" ); unsigned char * bytes = (unsigned char *)v; for (int i = 0 ; i < n * 4 ; i++) { if (bytes[i] >= 32 && bytes[i] <= 126 ) { printf ("%c" , bytes[i]); } else { printf ("\\x%02X" , bytes[i]); } } printf ("\n" ); return 0 ; }
介绍 XXTEA(Corrected Block TEA)是 XTEA 算法的优化升级版,专为解决 XTEA 对数据块长度的限制而生,能以 32 位无符号整数为基本单位,对任意长度的数据进行加密解密;它延续了轻量级特性,仅依赖基础算术与位运算,代码量少、资源占用低,同时优化了轮函数设计,增强抗攻击能力,广泛用于嵌入式设备、物联网终端、小型通信协议等对算力和存储要求严苛的场景。
最常魔改点 define DELTA 0x9e3779b9 这个数据经常被换。
加密原理
输入 :明文数组 v
(8个32位整数)、数组长度 n=8
、密钥 k
(4个32位整数)。
关键步骤 :
计算轮数 rounds = 6 + 52 / n
(确保充分混淆)。
初始化 sum = 0
,z = v[n-1]
。
多轮循环(每轮 sum += DELTA
(0x9e3779b9)):
计算 e = (sum >> 2) & 3
(动态选择密钥索引)。
遍历数组(除最后一个元素),使用 MX
函数更新每个 v[p]
:v[p] += MX
(MX
混合 y
(下一个元素)、z
(前一个元素)、密钥和 sum
)。
更新最后一个元素 v[n-1] += MX
(使用 y = v[0]
)。
输出 :密文数组 v
(原始明文被加密)。
解密原理
输入 :密文数组 v
、负长度 -n
(触发解密模式)、相同密钥 k
。
关键步骤 :
取 n
的绝对值,计算相同轮数 rounds
。
初始化 sum = rounds * DELTA
(加密最终值),y = v[0]
。
多轮循环(每轮 sum -= DELTA
):
计算 e
(同加密)。
反向遍历数组(从最后一个元素到第二个),使用 v[p] -= MX
(逆操作,恢复加密前值)。
更新第一个元素 v[0] -= MX
。
输出 :明文数组 v
(密文被解密)。