TEA加密算法的C/C++实现
生活随笔
收集整理的這篇文章主要介紹了
TEA加密算法的C/C++实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
TEA加密算法的C/C++實現(xiàn)http://www.xxlinux.com/linux/article/development/soft/20070911/9687.html |
| 時間:2007-09-11 11:02:34??來源:Linux聯(lián)盟收集整理??作者: |
| TEA(Tiny Encryption Algorithm)是一種簡單高效的加密算法,以加密解密速度快,實現(xiàn)簡單著稱。算法真的很簡單,TEA算法每一次可以操作64-bit(8-byte),采用128-bit(16-byte)作為key,算法采用迭代的形式,推薦的迭代輪數(shù)是64輪,最少32輪。目前我只知道QQ一直用的是16輪TEA。沒什么好說的,先給出C語言的源代碼(默認是32輪): 微型加密算法(TEA)及其相關(guān)變種(XTEA,Block?TEA,XXTEA)?都是分組加密算法,它們很容易被描述,實現(xiàn)也很簡單(典型的幾行代碼)。 TEA?算法最初是由劍橋計算機實驗室的?David?Wheeler?和?Roger?Needham?在?1994?年設(shè)計的。該算法使用?128?位的密鑰為?64?位的信息塊進行加密,它需要進行?64?輪迭代,盡管作者認為?32?輪已經(jīng)足夠了。該算法使用了一個神秘常數(shù)δ作為倍數(shù),它來源于黃金比率,以保證每一輪加密都不相同。但δ的精確值似乎并不重要,這里?TEA?把它定義為?δ=「(√5?-?1)231」(也就是程序中的?0×9E3779B9)。 之后?TEA?算法被發(fā)現(xiàn)存在缺陷,作為回應(yīng),設(shè)計者提出了一個?TEA?的升級版本——XTEA(有時也被稱為“tean”)。XTEA?跟?TEA?使用了相同的簡單運算,但它采用了截然不同的順序,為了阻止密鑰表攻擊,四個子密鑰(在加密過程中,原?128?位的密鑰被拆分為?4?個?32?位的子密鑰)采用了一種不太正規(guī)的方式進行混合,但速度更慢了。 在跟描述?XTEA?算法的同一份報告中,還介紹了另外一種被稱為?Block?TEA?算法的變種,它可以對?32?位大小任意倍數(shù)的變量塊進行操作。該算法將?XTEA?輪循函數(shù)依次應(yīng)用于塊中的每個字,并且將它附加于它的鄰字。該操作重復(fù)多少輪依賴于塊的大小,但至少需要?6?輪。該方法的優(yōu)勢在于它無需操作模式(CBC,OFB,CFB?等),密鑰可直接用于信息。對于長的信息它可能比?XTEA?更有效率。 在?1998?年,Markku-Juhani?Saarinen?給出了一個可有效攻擊?Block?TEA?算法的代碼,但之后很快?David?J.?Wheeler?和?Roger?M.?Needham?就給出了?Block?TEA?算法的修訂版,這個算法被稱為?XXTEA。XXTEA?使用跟?Block?TEA?相似的結(jié)構(gòu),但在處理塊中每個字時利用了相鄰字。它利用一個更復(fù)雜的?MX?函數(shù)代替了?XTEA?輪循函數(shù),MX?使用?2?個輸入量。 ?1?void?encrypt(unsigned?long?*v,?unsigned?long?*k)?{ ?2?????unsigned?long?y=v[0],?z=v[1],?sum=0,?i;?????????/*?set?up?*/ ?3?????unsigned?long?delta=0x9e3779b9;?????????????????/*?a?key?schedule?constant?*/ ?4?????unsigned?long?a=k[0],?b=k[1],?c=k[2],?d=k[3];???/*?cache?key?*/ ?5?????for?(i=0;?i?<?32;?i++)?{????????????????????????/*?basic?cycle?start?*/ ?6?????????sum?+=?delta; ?7?????????y?+=?((z<<4)?+?a)?^?(z?+?sum)?^?((z>>5)?+?b); ?8?????????z?+=?((y<<4)?+?c)?^?(y?+?sum)?^?((y>>5)?+?d);/*?end?cycle?*/ ?9?????} 10?????v[0]=y; 11?????v[1]=z; 12?} 13? 14?void?decrypt(unsigned?long?*v,?unsigned?long?*k)?{ 15?????unsigned?long?y=v[0],?z=v[1],?sum=0xC6EF3720,?i;?/*?set?up?*/ 16?????unsigned?long?delta=0x9e3779b9;??????????????????/*?a?key?schedule?constant?*/ 17?????unsigned?long?a=k[0],?b=k[1],?c=k[2],?d=k[3];????/*?cache?key?*/ 18?????for(i=0;?i<32;?i++)?{????????????????????????????/*?basic?cycle?start?*/ 19?????????z?-=?((y<<4)?+?c)?^?(y?+?sum)?^?((y>>5)?+?d); 20?????????y?-=?((z<<4)?+?a)?^?(z?+?sum)?^?((z>>5)?+?b); 21?????????sum?-=?delta;????????????????????????????????/*?end?cycle?*/ 22?????} 23?????v[0]=y; 24?????v[1]=z; 25?} C語言寫的用起來當(dāng)然不方便,沒關(guān)系,用C++封裝以下就OK了: util.h ?1?#ifndef?UTIL_H ?2?#define?UTIL_H ?3? ?4?#include?<string> ?5?#include?<cmath> ?6?#include?<cstdlib> ?7? ?8?typedef?unsigned?char?byte; ?9?typedef?unsigned?long?ulong; 10? 11?inline?double?logbase(double?base,?double?x)?{ 12?????return?log(x)/log(base); 13?} 14? 15?/* 16?*convert?int?to?hex?char. 17?*example:10?->?'A',15?->?'F' 18?*/ 19?char?intToHexChar(int?x); 20? 21?/* 22?*convert?hex?char?to?int. 23?*example:'A'?->?10,'F'?->?15 24?*/ 25?int?hexCharToInt(char?hex); 26? 27?using?std::string; 28?/* 29?*convert?a?byte?array?to?hex?string. 30?*hex?string?format?example:"AF?B0?80?7D" 31?*/ 32?string?bytesToHexString(const?byte?*in,?size_t?size); 33? 34?/* 35?*convert?a?hex?string?to?a?byte?array. 36?*hex?string?format?example:"AF?B0?80?7D" 37?*/ 38?size_t?hexStringToBytes(const?string?&str,?byte?*out); 39? 40?#endif/*UTIL_H*/ util.cpp ?1?#include?"util.h" ?2?#include?<vector> ?3? ?4?using?namespace?std; ?5? ?6?char?intToHexChar(int?x)?{ ?7?????static?const?char?HEX[16]?=?{ ?8?????????'0',?'1',?'2',?'3', ?9?????????'4',?'5',?'6',?'7', 10?????????'8',?'9',?'A',?'B', 11?????????'C',?'D',?'E',?'F' 12?????}; 13?????return?HEX[x]; 14?} 15? 16?int?hexCharToInt(char?hex)?{ 17?????hex?=?toupper(hex); 18?????if?(isdigit(hex)) 19?????????return?(hex?-?'0'); 20?????if?(isalpha(hex)) 21?????????return?(hex?-?'A'?+?10); 22?????return?0; 23?} 24? 25?string?bytesToHexString(const?byte?*in,?size_t?size)?{ 26?????string?str; 27?????for?(size_t?i?=?0;?i?<?size;?++i)?{ 28?????????int?t?=?in[i]; 29?????????int?a?=?t?/?16; 30?????????int?b?=?t?%?16; 31?????????str.append(1,?intToHexChar(a)); 32?????????str.append(1,?intToHexChar(b)); 33?????????if?(i?!=?size?-?1) 34?????????????str.append(1,?'?'); 35?????} 36?????return?str; 37?} 38? 39?size_t?hexStringToBytes(const?string?&str,?byte?*out)?{ 40? 41?????vector<string>?vec; 42?????string::size_type?currPos?=?0,?prevPos?=?0; 43?????while?((currPos?=?str.find('?',?prevPos))?!=?string::npos)?{ 44?????????string?b(str.substr(prevPos,?currPos?-?prevPos)); 45?????????vec.push_back(b); 46?????????prevPos?=?currPos?+?1; 47?????} 48?????if?(prevPos?<?str.size())?{ 49?????????string?b(str.substr(prevPos)); 50?????????vec.push_back(b); 51?????} 52?????typedef?vector<string>::size_type?sz_type; 53?????sz_type?size?=?vec.size(); 54?????for?(sz_type?i?=?0;?i?<?size;?++i)?{ 55?????????int?a?=?hexCharToInt(vec[i][0]); 56?????????int?b?=?hexCharToInt(vec[i][1]); 57?????????out[i]?=?a?*?16?+?b; 58?????} 59?????return?size; 60?} tea.h ?1?#ifndef?TEA_H ?2?#define?TEA_H ?3? ?4?/* ?5?*for?htonl,htonl ?6?*do?remember?link?"ws2_32.lib" ?7?*/ ?8?#include?<winsock2.h> ?9?#include?"util.h" 10? 11?class?TEA?{ 12?public: 13?????TEA(const?byte?*key,?int?round?=?32,?bool?isNetByte?=?false); 14?????TEA(const?TEA?&rhs); 15?????TEA&?operator=(const?TEA?&rhs); 16?????void?encrypt(const?byte?*in,?byte?*out); 17?????void?decrypt(const?byte?*in,?byte?*out); 18?private: 19?????void?encrypt(const?ulong?*in,?ulong?*out); 20?????void?decrypt(const?ulong?*in,?ulong?*out); 21?????ulong?ntoh(ulong?netlong)?{?return?_isNetByte???ntohl(netlong)?:?netlong;?} 22?????ulong?hton(ulong?hostlong)?{?return?_isNetByte???htonl(hostlong)?:?hostlong;?} 23?private: 24?????int?_round;?//iteration?round?to?encrypt?or?decrypt 25?????bool?_isNetByte;?//whether?input?bytes?come?from?network 26?????byte?_key[16];?//encrypt?or?decrypt?key 27?}; 28? 29?#endif/*TEA_H*/ tea.cpp ?1?#include?"tea.h" ?2?#include?<cstring>?//for?memcpy,memset ?3? ?4?using?namespace?std; ?5? ?6?TEA::TEA(const?byte?*key,?int?round?/*=?32*/,?bool?isNetByte?/*=?false*/) ?7?:_round(round) ?8?,_isNetByte(isNetByte)?{ ?9?????if?(key?!=?0) 10?????????memcpy(_key,?key,?16); 11?????else 12?????????memset(_key,?0,?16); 13?} 14? 15?TEA::TEA(const?TEA?&rhs) 16?:_round(rhs._round) 17?,_isNetByte(rhs._isNetByte)?{ 18?????memcpy(_key,?rhs._key,?16); 19?} 20? 21?TEA&?TEA::operator=(const?TEA?&rhs)?{ 22?????if?(&rhs?!=?this)?{ 23?????????_round?=?rhs._round; 24?????????_isNetByte?=?rhs._isNetByte; 25?????????memcpy(_key,?rhs._key,?16); 26?????} 27?????return?*this; 28?} 29? 30?void?TEA::encrypt(const?byte?*in,?byte?*out)?{ 31?????encrypt((const?ulong*)in,?(ulong*)out); 32?} 33? 34?void?TEA::decrypt(const?byte?*in,?byte?*out)?{ 35?????decrypt((const?ulong*)in,?(ulong*)out); 36?} 37? 38?void?TEA::encrypt(const?ulong?*in,?ulong?*out)?{ 39? 40?????ulong?*k?=?(ulong*)_key; 41?????register?ulong?y?=?ntoh(in[0]); 42?????register?ulong?z?=?ntoh(in[1]); 43?????register?ulong?a?=?ntoh(k[0]); 44?????register?ulong?b?=?ntoh(k[1]); 45?????register?ulong?c?=?ntoh(k[2]); 46?????register?ulong?d?=?ntoh(k[3]); 47?????register?ulong?delta?=?0x9E3779B9;?/*?(sqrt(5)-1)/2*2^32?*/ 48?????register?int?round?=?_round; 49?????register?ulong?sum?=?0; 50? 51?????while?(round--)?{????/*?basic?cycle?start?*/ 52?????????sum?+=?delta; 53?????????y?+=?((z?<<?4)?+?a)?^?(z?+?sum)?^?((z?>>?5)?+?b); 54?????????z?+=?((y?<<?4)?+?c)?^?(y?+?sum)?^?((y?>>?5)?+?d); 55?????}????/*?end?cycle?*/ 56?????out[0]?=?ntoh(y); 57?????out[1]?=?ntoh(z); 58?} 59? 60?void?TEA::decrypt(const?ulong?*in,?ulong?*out)?{ 61? 62?????ulong?*k?=?(ulong*)_key; 63?????register?ulong?y?=?ntoh(in[0]); 64?????register?ulong?z?=?ntoh(in[1]); 65?????register?ulong?a?=?ntoh(k[0]); 66?????register?ulong?b?=?ntoh(k[1]); 67?????register?ulong?c?=?ntoh(k[2]); 68?????register?ulong?d?=?ntoh(k[3]); 69?????register?ulong?delta?=?0x9E3779B9;?/*?(sqrt(5)-1)/2*2^32?*/ 70?????register?int?round?=?_round; 71?????register?ulong?sum?=?0; 72? 73?????if?(round?==?32) 74?????????sum?=?0xC6EF3720;?/*?delta?<<?5*/ 75?????else?if?(round?==?16) 76?????????sum?=?0xE3779B90;?/*?delta?<<?4*/ 77?????else 78?????????sum?=?delta?<<?static_cast<int>(logbase(2,?round)); 79? 80?????while?(round--)?{????/*?basic?cycle?start?*/ 81?????????z?-=?((y?<<?4)?+?c)?^?(y?+?sum)?^?((y?>>?5)?+?d); 82?????????y?-=?((z?<<?4)?+?a)?^?(z?+?sum)?^?((z?>>?5)?+?b); 83?????????sum?-=?delta; 84?????}????/*?end?cycle?*/ 85?????out[0]?=?ntoh(y); 86?????out[1]?=?ntoh(z); 87?} 需要說明的是TEA的構(gòu)造函數(shù): TEA(const byte *key, int round = 32, bool isNetByte = false); 1.key?- 加密或解密用的128-bit(16byte)密鑰。 2.round?- 加密或解密的輪數(shù),常用的有64,32,16。 3.isNetByte?- 用來標記待處理的字節(jié)是不是來自網(wǎng)絡(luò),為true時在加密/解密前先要轉(zhuǎn)換成本地字節(jié),執(zhí)行加密/解密,然后再轉(zhuǎn)換回網(wǎng)絡(luò)字節(jié)。偷偷告訴你,QQ就是這樣做的! 最后當(dāng)然少不了測試代碼: test.cpp ?1?#include?"tea.h" ?2?#include?"util.h" ?3?#include?<iostream> ?4? ?5?using?namespace?std; ?6? ?7?int?main()?{ ?8? ?9?????const?string?plainStr("AD?DE?E2?DB?B3?E2?DB?B3"); 10?????const?string?keyStr("3A?DA?75?21?DB?E2?DB?B3?11?B4?49?01?A5?C6?EA?D4"); 11?????const?int?SIZE_IN?=?8,?SIZE_OUT?=?8,?SIZE_KEY?=?16; 12?????byte?plain[SIZE_IN],?crypt[SIZE_OUT],?key[SIZE_KEY]; 13? 14?????size_t?size_in?=?hexStringToBytes(plainStr,?plain); 15?????size_t?size_key?=?hexStringToBytes(keyStr,?key); 16? 17?????if?(size_in?!=?SIZE_IN?||?size_key?!=?SIZE_KEY) 18?????????return?-1; 19? 20?????cout?<<?"Plain:?"?<<?bytesToHexString(plain,?size_in)?<<?endl; 21?????cout?<<?"Key??:?"?<<?bytesToHexString(key,?size_key)?<<?endl; 22? 23?????TEA?tea(key,?16,?true); 24?????tea.encrypt(plain,?crypt); 25?????cout?<<?"Crypt:?"?<<?bytesToHexString(crypt,?SIZE_OUT)?<<?endl; 26? 27?????tea.decrypt(crypt,?plain); 28?????cout?<<?"Plain:?"?<<?bytesToHexString(plain,?SIZE_IN)?<<?endl; 29?????return?0; 30?} 運行結(jié)果: Plain: AD DE E2 DB B3 E2 DB B3 Key? : 3A DA 75 21 DB E2 DB B3 11 B4 49 01 A5 C6 EA D4 Crypt: 3B 3B 4D 8C 24 3A FD F2 Plain: AD DE E2 DB B3 E2 DB B3 |
總結(jié)
以上是生活随笔為你收集整理的TEA加密算法的C/C++实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【转】使用TCP协议连续传输大量数据时,
- 下一篇: 双色球个数统计系统