Tiny Encryption Algorithm (微型加密算法)
性质 块加密,对称加密
块加密:将明文按一定大小分组之后用确定的算法和对称密钥对魅族分别加密,一般来说加密和解密函数为反函数,一般会进行多轮加密
对称加密:加密解密双方使用同一个密钥加密解密或双方使用的是两个可以简单地相互推算的密钥
过程 定义与初始化 1 2 key = [a,b,c,d] delta = 0x9E3779B9
轮加密 1 2 3 4 5 6 7 for i in (0 ,len (m),2 ): x = m[i] y = m[i+1 ] for j in range (32 ): delta++ x += ((y << 4 ) + Key[0 ]) ^ (y + delta) ^ ((y >> 5 ) + Key[1 ]) y += ((x << 4 ) + Key[2 ]) ^ (x + delta) ^ ((x >> 5 ) + Key[3 ])
注:具体算法可能不同,但是一般都是x 由y和key改变,y由x和key改变,delta可能加可能减,但是一般情况不会把for i in (0,len(m),2)改成for i in (len-1),这样就不是块加密了
此处省略了&0xffffffff,需要让所有值都是int/dword,下面也是,之后不说了
XTEA的加密部分:
1 2 3 4 for i in range (n): x += (((y << 4 ) ^ (y >> 5 )) + y) ^ (delta + key[delta & 3 ]) delta++ y += (((x << 4 ) ^ (x >> 5 )) + x) ^ (delta + key[(delta>>11 ) & 3 ])
注;相当于添加了与和位移,让key的取值不固定,但是框架没啥区别
XXTEA的加密部分
1 2 3 4 5 6 7 8 round = 6 + 52 // n MX = lambda sum , y, z, p, e, k: ((z >> 5 ^ y << 2 ) + (y >> 3 ^ z << 4 )) ^ ((sum ^ y) + (k[p & 3 ^ e] ^ z)) for i in range (round ): sum = (sum + DELTA) & 0xffffffff e = sum >> 2 & 3 for p in range (n): y = m[(p + 1 ) % n] z = m[p] = (m[p] + MX(sum , y, z, p, e, k)) & 0xffffffff
贴一个c语言版
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 #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 xxtea (uint32_t * v, int n, uint32_t * key) { 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[2 ] = {0x12345678 , 0x78563412 }; uint32_t k[4 ]= {0x1 , 0x2 , 0x3 , 0x4 }; int n = 2 ; printf ("Data is : %x %x\n" , v[0 ], v[1 ]); xxtea(v, n, k); printf ("Encrypted data is : %x %x\n" , v[0 ], v[1 ]); xxtea(v, -n, k); printf ("Decrypted data is : %x %x\n" , v[0 ], v[1 ]); return 0 ; }
修正:XXTEA和前面两个的区别在于:
前两个加密只是两个两个地相互加密,但是xxtea是用前一个值和后一个值加密这个位,按每个都加密一遍算一轮,一共进行round轮,这里放一个我理解的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 51 52 53 54 55 #include <iostream> #include <stdint.h> #include "Arr.h" int XXTEA (Arr& input, uint32_t * const key) { uint32_t delta = 0x9E3779B9 ; uint32_t sum = 0 ; uint32_t len = input.getsize (); uint32_t round = 52 / len + 6 ; for (int i = 0 ; i < round; i++) { sum += delta; for (int now = 0 ; now < len; now++) { input[now] += (((input[now - 1 ] >> 5 ^ input[now + 1 ] << 2 ) + (input[now + 1 ] >> 3 ^ input[now - 1 ] << 4 )) ^ ((sum ^ input[now + 1 ]) + (key[(now & 3 ) ^ ((sum >> 2 ) & 3 )] ^ input[now - 1 ]))); } } return 0 ; } int deXXTEA (Arr& input, uint32_t * const key) { uint32_t delta = 0x9E3779B9 ; uint32_t len = input.getsize (); uint32_t round = 52 / len + 6 ; uint32_t sum = delta * round; for (int i = 0 ; i < round; i++) { for (int now = len - 1 ; now > -1 ; now--) { input[now] -= (((input[now - 1 ] >> 5 ^ input[now + 1 ] << 2 ) + (input[now + 1 ] >> 3 ^ input[now - 1 ] << 4 )) ^ ((sum ^ input[now + 1 ]) + (key[(now & 3 ) ^ ((sum >> 2 ) & 3 )] ^ input[now - 1 ]))); } sum -= delta; } return 0 ; } int main (void ) { Arr* test = new Arr ((uint32_t *)"HELLO_MESSAGE_he" , 4 ); uint32_t const key[4 ] = { 2 ,2 ,3 ,4 }; XXTEA (*test, (uint32_t *)key); std::cout << *test; deXXTEA (*test, (uint32_t *)key); std::cout << *test; std::cout << (char *)test->getarr (); 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 #pragma once #include <initializer_list> #include <algorithm> #include <iostream> #include <iomanip> #include <cstring> class Arr { private : size_t size; unsigned int * arr; public : Arr (size_t s); Arr (uint32_t * p, unsigned s); Arr (std::initializer_list<unsigned int > init); ~Arr (); unsigned int getsize () const ; unsigned int * getarr () const ; friend std::ostream& operator <<(std::ostream& os, const Arr& obj); unsigned int & operator [](unsigned i); unsigned int * begin () const ; unsigned int * end () const ; };
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 #include "Arr.h" Arr::Arr (size_t s) : size (s), arr (new uint32_t [s]) { std::fill_n (arr, s, 0 ); } Arr::Arr (uint32_t * p, unsigned s) : Arr (s) { for (size_t i = 0 ; i < size; i++) { arr[i] = p[i]; } } Arr::Arr (std::initializer_list<unsigned int > init) :size (init.size ()), arr (new unsigned int [init.size ()]) { std::copy (init.begin (), init.end (), arr); } Arr::~Arr () { delete [] arr; } unsigned int Arr::getsize () const { return size; } unsigned int * Arr::getarr () const { return arr; } unsigned int & Arr::operator [](unsigned i){ i = (i + size) % size; i = i >= 0 ? i : (i + size); return arr[i]; } unsigned int * Arr::begin () const { return arr; } unsigned int * Arr::end () const { return arr + size; } std::ostream& operator <<(std::ostream& os, const Arr& obj) { os << "len: " << obj.getsize () << std::endl; os << "element list:" << std::endl; for (unsigned i : obj) { os << "0x" << std::hex << std::uppercase << std::setw (8 ) << std::setfill ('0' ) << i << std::endl; } return os; }
破解方法 缺陷 似乎网上很多blog都提到了密钥表攻击TEA,但是我没找到
[等待施工][QAQ]