|
 |
栏目导栏 |
|
| |
|
|
|
|
 |
资料搜索 |
|
| |
|
|
|
|
 |
热门文章 |
|
| |
|
|
|
|
 |
最新文章 |
|
| |
|
|
|
| |
| |
|
|
|
|
TEA(Tiny Encryption Algorithm) 是一种简单高效的加密算法,以加密解密速度快,实现简单著称。算法真的很简单,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。目前我只知道QQ一直用的是16轮TEA。没什么好说的,先给出C语言的源代码(默认是32轮): 微型加密算法(TEA)及其相关变种(XTEA,Block TEA,XXTEA) 都是分组加密算法,它们很容易被描述,实现也很简单(典型的几行代码)。azhLinux联盟 azhLinux联盟 TEA 算法最初是由剑桥计算机实验室的 David Wheeler 和 Roger Needham 在 1994 年设计的。该算法使用 128 位的密钥为 64 位的信息块进行加密,它需要进行 64 轮迭代,尽管作者认为 32 轮已经足够了。该算法使用了一个神秘常数δ作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9)。azhLinux联盟 azhLinux联盟 之后 TEA 算法被发现存在缺陷,作为回应,设计者提出了一个 TEA 的升级版本——XTEA(有时也被称为“tean”)。XTEA 跟 TEA 使用了相同的简单运算,但它采用了截然不同的顺序,为了阻止密钥表攻击,四个子密钥(在加密过程中,原 128 位的密钥被拆分为 4 个 32 位的子密钥)采用了一种不太正规的方式进行混合,但速度更慢了。azhLinux联盟 azhLinux联盟 在跟描述 XTEA 算法的同一份报告中,还介绍了另外一种被称为 Block TEA 算法的变种,它可以对 32 位大小任意倍数的变量块进行操作。该算法将 XTEA 轮循函数依次应用于块中的每个字,并且将它附加于它的邻字。该操作重复多少轮依赖于块的大小,但至少需要 6 轮。该方法的优势在于它无需操作模式(CBC,OFB,CFB 等),密钥可直接用于信息。对于长的信息它可能比 XTEA 更有效率。azhLinux联盟 azhLinux联盟 在 1998 年,Markku-Juhani Saarinen 给出了一个可有效攻击 Block TEA 算法的代码,但之后很快 David J. Wheeler 和 Roger M. Needham 就给出了 Block TEA 算法的修订版,这个算法被称为 XXTEA。XXTEA 使用跟 Block TEA 相似的结构,但在处理块中每个字时利用了相邻字。它利用一个更复杂的 MX 函数代替了 XTEA 轮循函数,MX 使用 2 个输入量。azhLinux联盟
1 void encrypt(unsigned long *v, unsigned long *k) {azhLinux联盟 2 unsigned long y=v[0], z=v[1], sum=0, i; /* set up */azhLinux联盟 3 unsigned long delta=0x9e3779b9; /* a key schedule constant */azhLinux联盟 4 unsigned long a=k[0], b=k[1], c=k[2], d=k[3]; /* cache key */azhLinux联盟 5 for (i=0; i < 32; i++) { /* basic cycle start */azhLinux联盟 6 sum += delta;azhLinux联盟 7 y += ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);azhLinux联盟 8 z += ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);/* end cycle */azhLinux联盟 9 }azhLinux联盟 10 v[0]=y;azhLinux联盟 11 v[1]=z;azhLinux联盟 12 }azhLinux联盟 13 azhLinux联盟 14 void decrypt(unsigned long *v, unsigned long *k) {azhLinux联盟 15 unsigned long y=v[0], z=v[1], sum=0xC6EF3720, i; /* set up */azhLinux联盟 16 unsigned long delta=0x9e3779b9; /* a key schedule constant */azhLinux联盟 17 unsigned long a=k[0], b=k[1], c=k[2], d=k[3]; /* cache key */azhLinux联盟 18 for(i=0; i<32; i++) { /* basic cycle start */azhLinux联盟 19 z -= ((y<<4) + c) ^ (y + sum) ^ ((y>>5) + d);azhLinux联盟 20 y -= ((z<<4) + a) ^ (z + sum) ^ ((z>>5) + b);azhLinux联盟 21 sum -= delta; /* end cycle */azhLinux联盟 22 }azhLinux联盟 23 v[0]=y;azhLinux联盟 24 v[1]=z;azhLinux联盟 25 } azhLinux联盟C语言写的用起来当然不方便,没关系,用C++封装以下就OK了: azhLinux联盟util.hazhLinux联盟
1 #ifndef UTIL_HazhLinux联盟 2 #define UTIL_HazhLinux联盟 3 azhLinux联盟 4 #include <string>azhLinux联盟 5 #include <cmath>azhLinux联盟 6 #include <cstdlib>azhLinux联盟 7 azhLinux联盟 8 typedef unsigned char byte;azhLinux联盟 9 typedef unsigned long ulong;azhLinux联盟 10 azhLinux联盟 11 inline double logbase(double base, double x) {azhLinux联盟 12 return log(x)/log(base);azhLinux联盟 13 }azhLinux联盟 14 azhLinux联盟 15 /*azhLinux联盟 16 *convert int to hex char.azhLinux联盟 17 *example:10 -> 'A',15 -> 'F'azhLinux联盟 18 */azhLinux联盟 19 char intToHexChar(int x);azhLinux联盟 20 azhLinux联盟 21 /*azhLinux联盟 22 *convert hex char to int.azhLinux联盟 23 *example:'A' -> 10,'F' -> 15azhLinux联盟 24 */azhLinux联盟 25 int hexCharToInt(char hex);azhLinux联盟 26 azhLinux联盟 27 using std::string;azhLinux联盟 28 /*azhLinux联盟 29 *convert a byte array to hex string.azhLinux联盟 30 *hex string format example:"AF B0 80 7D"azhLinux联盟 31 */azhLinux联盟 32 string bytesToHexString(const byte *in, size_t size);azhLinux联盟 33 azhLinux联盟 34 /*azhLinux联盟 35 *convert a hex string to a byte array.azhLinux联盟 36 *hex string format example:"AF B0 80 7D"azhLinux联盟 37 */azhLinux联盟 38 size_t hexStringToBytes(const string &str, byte *out);azhLinux联盟 39 azhLinux联盟 40 #endif/*UTIL_H*/ azhLinux联盟util.cppazhLinux联盟
1 #include "util.h"azhLinux联盟 2 #include <vector>azhLinux联盟 3 azhLinux联盟 4 using namespace std;azhLinux联盟 5 azhLinux联盟 6 char intToHexChar(int x) {azhLinux联盟 7 static const char HEX[16] = {azhLinux联盟 8 '0', '1', '2', '3',azhLinux联盟 9 '4', '5', '6', '7',azhLinux联盟 10 '8', '9', 'A', 'B',azhLinux联盟 11 'C', 'D', 'E', 'F'azhLinux联盟 12 };azhLinux联盟 13 return HEX[x];azhLinux联盟 14 }azhLinux联盟 15 azhLinux联盟 16 int hexCharToInt(char hex) {azhLinux联盟 17 hex = toupper(hex);azhLinux联盟 18 if (isdigit(hex))azhLinux联盟 19 return (hex - '0');azhLinux联盟 20 if (isalpha(hex))azhLinux联盟 21 return (hex - 'A' + 10);azhLinux联盟 22 return 0;azhLinux联盟 23 }azhLinux联盟 24 azhLinux联盟 25 string bytesToHexString(const byte *in, size_t size) {azhLinux联盟 26 string str;azhLinux联盟 27 for (size_t i = 0; i < size; ++i) {azhLinux联盟 28 int t = in[i];azhLinux联盟 29 int a = t / 16;azhLinux联盟 30 int b = t % 16;azhLinux联盟 31 str.append(1, intToHexChar(a));azhLinux联盟 32 str.append(1, intToHexChar(b));azhLinux联盟 33 if (i != size - 1)azhLinux联盟 34 str.append(1, ' ');azhLinux联盟 35 }azhLinux联盟 36 return str;azhLinux联盟 37 }azhLinux联盟 38 azhLinux联盟 39 size_t hexStringToBytes(const string &str, byte *out) {azhLinux联盟 40 azhLinux联盟 41 vector<string> vec;azhLinux联盟 42 string::size_type currPos = 0, prevPos = 0;azhLinux联盟 43 while ((currPos = str.find(' ', prevPos)) != string::npos) {azhLinux联盟 44 string b(str.substr(prevPos, currPos - prevPos));azhLinux联盟 45 vec.push_back(b);azhLinux联盟 46 prevPos = currPos + 1;azhLinux联盟 47 }azhLinux联盟 48 if (prevPos < str.size()) {azhLinux联盟 49 string b(str.substr(prevPos));azhLinux联盟 50 vec.push_back(b);azhLinux联盟 51 }azhLinux联盟 52 typedef vector<string>::size_type sz_type;azhLinux联盟 53 sz_type size = vec.size();azhLinux联盟 54 for (sz_type i = 0; i < size; ++i) {azhLinux联盟 55 int a = hexCharToInt(vec[i][0]);azhLinux联盟 56 int b = hexCharToInt(vec[i][1]);azhLinux联盟 57 out[i] = a * 16 + b;azhLinux联盟 58 }azhLinux联盟 59 return size;azhLinux联盟 60 } azhLinux联盟tea.hazhLinux联盟
1 #ifndef TEA_HazhLinux联盟 2 #define TEA_HazhLinux联盟 3 azhLinux联盟 4 /*azhLinux联盟 5 *for htonl,htonlazhLinux联盟 6 *do remember link "ws2_32.lib"azhLinux联盟 7 */azhLinux联盟 8 #include <winsock2.h>azhLinux联盟 9 #include "util.h"azhLinux联盟 10 azhLinux联盟 11 class TEA {azhLinux联盟 12 public:azhLinux联盟 13 TEA(const byte *key, int round = 32, bool isNetByte = false);azhLinux联盟 14 TEA(const TEA &rhs);azhLinux联盟 15 TEA& operator=(const TEA &rhs);azhLinux联盟 16 void encrypt(const byte *in, byte *out);azhLinux联盟 17 void decrypt(const byte *in, byte *out);azhLinux联盟 18 private:azhLinux联盟 19 void encrypt(const ulong *in, ulong *out);azhLinux联盟 20 void decrypt(const ulong *in, ulong *out);azhLinux联盟 21 ulong ntoh(ulong netlong) { return _isNetByte ? ntohl(netlong) : netlong; }azhLinux联盟 22 ulong hton(ulong hostlong) { return _isNetByte ? htonl(hostlong) : hostlong; }azhLinux联盟 23 private:azhLinux联盟 24 int _round; //iteration round to encrypt or decryptazhLinux联盟 25 bool _isNetByte; //whether input bytes come from networkazhLinux联盟 26 byte _key[16]; //encrypt or decrypt keyazhLinux联盟 27 };azhLinux联盟 28 azhLinux联盟 29 #endif/*TEA_H*/ azhLinux联盟 tea.cppazhLinux联盟
1 #include "tea.h"azhLinux联盟 2 #include <cstring> //for memcpy,memsetazhLinux联盟 3 azhLinux联盟 4 using namespace std;azhLinux联盟 5 azhLinux联盟 6 TEA::TEA(const byte *key, int round /*= 32*/, bool isNetByte /*= false*/)azhLinux联盟 7 :_round(round)azhLinux联盟 8 ,_isNetByte(isNetByte) {azhLinux联盟 9 if (key != 0)azhLinux联盟 10 memcpy(_key, key, 16);azhLinux联盟 11 elseazhLinux联盟 12 memset(_key, 0, 16);azhLinux联盟 13 }azhLinux联盟 14 azhLinux联盟 15 TEA::TEA(const TEA &rhs)azhLinux联盟 16 :_round(rhs._round)azhLinux联盟 17 ,_isNetByte(rhs._isNetByte) {azhLinux联盟 18 memcpy(_key, rhs._key, 16);azhLinux联盟 19 }azhLinux联盟 20 azhLinux联盟 21 TEA& TEA::operator=(const TEA &rhs) {azhLinux联盟 22 if (&rhs != this) {azhLinux联盟 23 _round = rhs._round;azhLinux联盟 24 _isNetByte = rhs._isNetByte;azhLinux联盟 25 memcpy(_key, rhs._key, 16);azhLinux联盟 26 }azhLinux联盟 27 return *this;azhLinux联盟 28 }azhLinux联盟 29 azhLinux联盟 30 void TEA::encrypt(const byte *in, byte *out) {azhLinux联盟 31 encrypt((const ulong*)in, (ulong*)out);azhLinux联盟 32 }azhLinux联盟 33 azhLinux联盟 34 void TEA::decrypt(const byte *in, byte *out) {azhLinux联盟 35 decrypt((const ulong*)in, (ulong*)out);azhLinux联盟 36 }azhLinux联盟 37 azhLinux联盟 38 void TEA::encrypt(const ulong *in, ulong *out) {azhLinux联盟 39 azhLinux联盟 40 ulong *k = (ulong*)_key;azhLinux联盟 41 register ulong y = ntoh(in[0]);azhLinux联盟 42 register ulong z = ntoh(in[1]);azhLinux联盟 43 register ulong a = ntoh(k[0]);azhLinux联盟 44 register ulong b = ntoh(k[1]);azhLinux联盟 45 register ulong c = ntoh(k[2]);azhLinux联盟 46 register ulong d = ntoh(k[3]);azhLinux联盟 47 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */azhLinux联盟 48 register int round = _round;azhLinux联盟 49 register ulong sum = 0;azhLinux联盟 50 azhLinux联盟 51 while (round--) { /* basic cycle start */azhLinux联盟 52 sum += delta;azhLinux联盟 53 y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);azhLinux联盟 54 z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);azhLinux联盟 55 } /* end cycle */azhLinux联盟 56 out[0] = ntoh(y);azhLinux联盟 57 out[1] = ntoh(z);azhLinux联盟 58 }azhLinux联盟 59 azhLinux联盟 60 void TEA::decrypt(const ulong *in, ulong *out) {azhLinux联盟 61 azhLinux联盟 62 ulong *k = (ulong*)_key;azhLinux联盟 63 register ulong y = ntoh(in[0]);azhLinux联盟 64 register ulong z = ntoh(in[1]);azhLinux联盟 65 register ulong a = ntoh(k[0]);azhLinux联盟 66 register ulong b = ntoh(k[1]);azhLinux联盟 67 register ulong c = ntoh(k[2]);azhLinux联盟 68 register ulong d = ntoh(k[3]);azhLinux联盟 69 register ulong delta = 0x9E3779B9; /* (sqrt(5)-1)/2*2^32 */azhLinux联盟 70 register int round = _round;azhLinux联盟 71 register ulong sum = 0;azhLinux联盟 72 azhLinux联盟 73 if (round == 32)azhLinux联盟 74 sum = 0xC6EF3720; /* delta << 5*/azhLinux联盟 75 else if (round == 16)azhLinux联盟 76 sum = 0xE3779B90; /* delta << 4*/azhLinux联盟 77 elseazhLinux联盟 78 sum = delta << static_cast<int>(logbase(2, round));azhLinux联盟 79 azhLinux联盟 80 while (round--) { /* basic cycle start */azhLinux联盟 81 z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);azhLinux联盟 82 y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);azhLinux联盟 83 sum -= delta;azhLinux联盟 84 } /* end cycle */azhLinux联盟 85 out[0] = ntoh(y);azhLinux联盟 86 out[1] = ntoh(z);azhLinux联盟 87 } azhLinux联盟 需要说明的是TEA的构造函数:azhLinux联盟 TEA(const byte *key, int round = 32, bool isNetByte = false);azhLinux联盟 1.key - 加密或解密用的128-bit(16byte)密钥。azhLinux联盟 2.round - 加密或解密的轮数,常用的有64,32,16。azhLinux联盟 3.isNetByte - 用来标记待处理的字节是不是来自网络,为true时在加密/解密前先要转换成本地字节,执行加密/解密,然后再转换回网络字节。偷偷告诉你,QQ就是这样做的!azhLinux联盟 azhLinux联盟 最后当然少不了测试代码:azhLinux联盟 test.cppazhLinux联盟
1 #include "tea.h"azhLinux联盟 2 #include "util.h"azhLinux联盟 3 #include <iostream>azhLinux联盟 4 azhLinux联盟 5 using namespace std;azhLinux联盟 6 azhLinux联盟 7 | |