tea加密算法及其变种的研究
tea
介绍
"TEA" 的全称为"Tiny Encryption Algorithm" 是1994年由英国剑桥大学的David j.wheeler发明的.
TEA算法也算是微型加密算法
在安全学领域,TEA(Tiny Encryption Algorithm)是一种分组加密(CBC)算法,它的实现非常简单,通常只需要很精短的几行代码。
分组加密(CBC)加密
CBC模式的加密方式是通过一个初始向量(IV)先和明文分组第一组异或后使用秘钥K加密,作为第一组密文,同时又与后一分组的明文异或后进行加密产生下一组密文,依次重复。
其解密和加密是对称的,密文先解密,再异或。
其特点如下:
- 明文有一组中有错,会使以后的密文组都受影响,但经解密后的恢复结果,除原有误的一组外,其后各组明文都正确地恢复。
- 解密时,有一组秘钥错误,该错误会影响下一分组相同位置的解密
- 若在传送过程中,某组密文组出错时,则该组恢复的明文和下一组恢复数据出错。再后面的组将不会受中错误比特的影响
加密图及实现
tea加密至少需要两个数据,通常为64位8字节,同时需要一个delta值,delta每次迭代倍增,一般为0x9E3779B9,有一个128位密钥,一般分为4个32位密钥,每组加密一般进行32轮迭代。
C语言实现
void Encrypt(long* EntryData, long* Key) { //分别加密数组中的前四个字节与后4个字节,4个字节为一组每次加密两组 unsigned long x = EntryData[0]; unsigned long y = EntryData[1]; unsigned long sum = 0;//迭代器 unsigned long delta = 0x9E3779B9;//delta值 //总共加密32轮 for (int i = 0; i < 32; i++) { sum += delta;//delata倍增 x += ((y << 4) + Key[0]) ^ (y + sum) ^ ((y >> 5) + Key[1]); y += ((x << 4) + Key[2]) ^ (x + sum) ^ ((x >> 5) + Key[3]); } //最后加密的结果重新写入到数组中 EntryData[0] = x; EntryData[1] = y; }
xtea
最大的不同在于,xtea的sum第一次加密为0,subkey的取值方式为sum中的两个二进制位,一般一个是最后两个,一个是左移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;//注意于tea的区别 v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum>>11) & 3]); } v[0]=v0; v[1]=v1; }
xxtea
相比xtea与tea,xxtea的复杂度更上了一层,subkey的方式变为已进行的轮数的最后两位与delta叠加的最后两位相异或,delta迭代与tea相同
#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) // encrypt { 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) // decrypt { 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); } } // test int main() { // 两个32位无符号整数,即待加密的64bit明文数据 uint32_t v[2] = {0x12345678, 0x78563412}; // 四个32位无符号整数,即128bit的key uint32_t k[4]= {0x1, 0x2, 0x3, 0x4}; //n的绝对值表示v的长度,取正表示加密,取负表示解密 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; }