導航:首頁 > 源碼編譯 > tea演算法詳解

tea演算法詳解

發布時間:2023-04-29 16:25:02

❶ tea 演算法的原理

TEA加密和解密時都使用一個常量值,這個常量值為0x9e3779b,這個值是近似黃金分割率,注意,有些編程人員為了避免在程序中直接出現"mov 變數,0x9e3779b",以免被破解者直接搜索0x9e3779b這個常數得知使用TEA演算法,所以有時會使用"sub 變數,0x61C88647"代替"mov 變數,0x9e3779b",0x61C88647=-(0x9e3779b)。

TEA演算法每一次可以操作64bit(8byte),採用128bit(16byte)作為key,演算法採用迭代的形式,推薦的迭代輪數是64輪,最少32輪。

❷ tea加解密演算法經過Keil編譯單片機中運行結果錯誤,求幫助

c並沒有規定int,long 之類的數據類型對應幾個char,所以造成按位運算在不同的編譯器下運行結果不一樣
解決辦法
#define int8 char
#define uint8 uchar
#define int16 int //16位mcu
#define int16 (short int)//32位mcu
.......
這個樣子就可以避免數據類型的差異所帶來的影響(不知道int代表幾個char,就用sizeof(int))
還有,你的long btea(long* v,char n,long* k);
而你調用的時候btea(plainbuffer, 2,key);
函數簽名和定義的數據類型不一致,也會發生錯誤(不要以為unsigned可有可無)
你這樣調整一下,應該就沒有問題了

❸ TEA加密演算法的應用

QQTEA 演算法建立在標准 TEA演算法的基礎上,使用16輪的加密(這是最低限,推薦應該是32輪)。QQ在使用這個演算法的時候,由於需要加密不定長的數據,所以使用了一些常規的填充辦法和交織演算法。
1 填充演算法
如果明文本身的長度不是8的倍數,那麼還要進行填充以使其成為8的倍數。以位元組為單位,令N=原始字元串+10+填充位元組數n,則N應該是8的倍數。
具體的填充方法:第一個位元組為:(random()&0xf8)|n,隨後填充(n+2)個位元組random()&0xff ,後面接原始數據,最後填充7 個位元組0x00 。
因為使用了不同的隨機數,所以填充的結果使得即使對於相同的明文,密文的結果也會不同。
2 交織演算法
消息被分為多個加密單元,每一個加密單元都是8位元組,使用TEA進行加密,加密結果與下一個加密單元做異或運算後再作為待加密的明文。

❹ 招新——第一次嘗試破解tea演算法

           開始接觸逆向分析時,入門級別的一道題目,是一個師兄寫的考核題《sotired》,嘗試著破解了下,以下是具體的過程。

1、雙擊發現打不開,應該是linux系統下的文件(事實證明確實如此,我在虛擬機那裡驗證了一下,隨便輸入字元串,得到的答案是sorry~,給人crakeme的感覺,哈哈)

2、使用反匯編工具ida64位,將文件拖進去,找到main函數,使用F5大法,得到下面的界面:

看到sorry~和wow!congratulation!的字元串,可以推斷出有字元串的對比,看到if語句,沒錯就是它了,看來temp[k]裡面有我們想要的東西(用於匹配比較的正確密文)點進去,得到

這里利用一個小插件lazyida,哈哈哈(我比較懶),得到密文,

在這里需要聲明下,因為最後讀出來的那個0x00111885B有誤(lazyida的原因),其實是0x32111885B才對,所以是 0x572CB9C1, 0x73A6EB63, 0x069E6A55, 0x818E33D9, 0x7ED0A862, 0x3211885B,這些16進制的數就是密文啦!有了密文,我們要破解它,就需要找密鑰啦,回去看函數

想像下,用戶輸入一組字元串,for循環了3次,atoui函數猜測應該是某種轉換函數,點進去

果然是移位加密轉換,結果是int 型,所以v11[6]的字元數據全部被轉換了數字,繼續往下

又有3次循環,看到encipher函數應該是加密函數來的,然後傳遞了兩個參數,一個是轉化後的v11,另一個v7,這里就可以懷疑了,v7應該是密鑰,而且用了引用,難道是地址嗎?很奇怪,點進去v7,得到

這里又要懷疑了,前面4個都是?一個數字有4個數據,感覺很像數組的樣子,於是嘗試一波

轉換為數組,然後F5大法刷新下!得到

看來我們的推斷是正確的,v7是一個數組,裡面的數據應該是密鑰了!到此,我們成功地拿到了密文和密鑰了,接下來就是解密了,解密前需要知道是怎麼加密的,回到剛剛的encipher函數,進去

看到這里有人可能要很激動了,這個演算法不就是tea演算法嗎?!(沒錯,雖然我一開始也不知道,於是我去谷歌了一波!)

tea演算法就是把密文結合密鑰進行移位再異或的運算,總共進行32輪。解密則是反過來求解,不過需要先算出delta的值,即9e3779b9*32後得到13c6ef3720,明顯溢出了(手賤算了下,溢出。tea演算法把溢出的忽略了,emmmm,我也不太懂其中的原因,能用先用著,哈哈哈),於是乎,可以寫腳本了,打開c++,寫入腳本

我們的密文和密鑰修改好後,因為有密文有6個16進制的數,所以解密3次,得到結果

好啦,這就是我們的flag了,但是看不懂是吧,沒關系,去轉換下,谷歌走起!

大家記得把空格消除,然後把它和在一起轉化,好啦,虛擬機linux操作系統打開,文件打開,輸入flag,得到的就是WOw!congratulation!

以上便是我花了一個下午整理出來的一個逆向題目,希望對大家有幫助,也希望能多多交流哦,嘻嘻~

❺ 如何實現php的TEA演算法

演算法簡單,而且效率高,每次可以操作8個位元組的數據,加密解密的KEY為16位元組,即包含4個int數據的int型數組,加密輪數應為8的倍數,一般比較常用的輪數為64,32,16,QQ原來就是用TEA16來還原密碼的.


TEA演算法

核心為:

#include<stdint.h>

voidencrypt(uint32_t*v,uint32_t*k){
uint32_tv0=v[0],v1=v[1],sum=0,i;/*setup*/
uint32_tdelta=0x9e3779b9;/*akeyscheleconstant*/
uint32_tk0=k[0],k1=k[1],k2=k[2],k3=k[3];/*cachekey*/
for(i=0;i<32;i++){/*basiccyclestart*/
sum+=delta;
v0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);
v1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);
}/*endcycle*/
v[0]=v0;v[1]=v1;
}

voiddecrypt(uint32_t*v,uint32_t*k){
uint32_tv0=v[0],v1=v[1],sum=0xC6EF3720,i;/*setup*/
uint32_tdelta=0x9e3779b9;/*akeyscheleconstant*/
uint32_tk0=k[0],k1=k[1],k2=k[2],k3=k[3];/*cachekey*/
for(i=0;i<32;i++){/*basiccyclestart*/
v1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);
v0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);
sum-=delta;
}/*endcycle*/
v[0]=v0;v[1]=v1;
}


PHP部分代碼非我原創,大家可以了解一下這方面的知識

<?php
$date='8345354023476-3434';
$key='12345';
$t=newtea();
$tea=$t->encrypt($date,$key);
$eetea=$t->decrypt($tea,$key);
var_mp($tea);
var_mp($eetea);
classtea{
private$a,$b,$c,$d;
private$n_iter;
publicfunction__construct(){
$this->setIter(32);
}
privatefunctionsetIter($n_iter){
$this->n_iter=$n_iter;
}
privatefunctiongetIter(){
return$this->n_iter;
}
publicfunctionencrypt($data,$key){
//resizedatato32bits(4bytes)
$n=$this->_resize($data,4);

//convertdatatolong
$data_long[0]=$n;
$n_data_long=$this->_str2long(1,$data,$data_long);

//resizedata_longto64bits(2longsof32bits)
$n=count($data_long);
if(($n&1)==1){
$data_long[$n]=chr(0);
$n_data_long++;
}

//resizekeytoamultipleof128bits(16bytes)
$this->_resize($key,16,true);
if(''==$key)
$key='0000000000000000';

//convertkeytolong
$n_key_long=$this->_str2long(0,$key,$key_long);

//encryptthelongdatawiththekey
$enc_data='';
$w=array(0,0);
$j=0;
$k=array(0,0,0,0);
for($i=0;$i<$n_data_long;++$i){
//getnextkeypartof128bits
if($j+4<=$n_key_long){
$k[0]=$key_long[$j];
$k[1]=$key_long[$j+1];
$k[2]=$key_long[$j+2];
$k[3]=$key_long[$j+3];
}else{
$k[0]=$key_long[$j%$n_key_long];
$k[1]=$key_long[($j+1)%$n_key_long];
$k[2]=$key_long[($j+2)%$n_key_long];
$k[3]=$key_long[($j+3)%$n_key_long];
}
$j=($j+4)%$n_key_long;

$this->_encipherLong($data_long[$i],$data_long[++$i],$w,$k);

//
$enc_data.=$this->_long2str($w[0]);
$enc_data.=$this->_long2str($w[1]);
}

return$enc_data;
}
publicfunctiondecrypt($enc_data,$key){
//convertdatatolong
$n_enc_data_long=$this->_str2long(0,$enc_data,$enc_data_long);

//resizekeytoamultipleof128bits(16bytes)
$this->_resize($key,16,true);
if(''==$key)
$key='0000000000000000';

//convertkeytolong
$n_key_long=$this->_str2long(0,$key,$key_long);

//decryptthelongdatawiththekey
$data='';
$w=array(0,0);
$j=0;
$len=0;
$k=array(0,0,0,0);
$pos=0;

for($i=0;$i<$n_enc_data_long;$i+=2){
//getnextkeypartof128bits
if($j+4<=$n_key_long){
$k[0]=$key_long[$j];
$k[1]=$key_long[$j+1];
$k[2]=$key_long[$j+2];
$k[3]=$key_long[$j+3];
}else{
$k[0]=$key_long[$j%$n_key_long];
$k[1]=$key_long[($j+1)%$n_key_long];
$k[2]=$key_long[($j+2)%$n_key_long];
$k[3]=$key_long[($j+3)%$n_key_long];
}
$j=($j+4)%$n_key_long;

$this->_decipherLong($enc_data_long[$i],$enc_data_long[$i+1],$w,$k);

//(removepadding)
if(0==$i){
$len=$w[0];
if(4<=$len){
$data.=$this->_long2str($w[1]);
}else{
$data.=substr($this->_long2str($w[1]),0,$len%4);
}
}else{
$pos=($i-1)*4;
if($pos+4<=$len){
$data.=$this->_long2str($w[0]);

if($pos+8<=$len){
$data.=$this->_long2str($w[1]);
}elseif($pos+4<$len){
$data.=substr($this->_long2str($w[1]),0,$len%4);
}
}else{
$data.=substr($this->_long2str($w[0]),0,$len%4);
}
}
}
return$data;
}
privatefunction_encipherLong($y,$z,&$w,&$k){
$sum=(integer)0;
$delta=0x9E3779B9;
$n=(integer)$this->n_iter;

while($n-->0){
//Cv0+=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);
//Cv1+=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);
$sum=$this->_add($sum,$delta);
$y=$this->_add($y,$this->_add(($z<<4),$this->a)^$this->_add($z,$sum)^$this->_add($this->_rshift($z,5),$this->b));
$z=$this->_add($z,$this->_add(($y<<4),$this->a)^$this->_add($y,$sum)^$this->_add($this->_rshift($y,5),$this->b));
}

$w[0]=$y;
$w[1]=$z;
}
privatefunction_decipherLong($y,$z,&$w,&$k){
//sum=delta<<5,ingeneralsum=delta*n
$sum=0xC6EF3720;
$delta=0x9E3779B9;
$n=(integer)$this->n_iter;

while($n-->0){
//Cv1-=((v0<<4)+k2)^(v0+sum)^((v0>>5)+k3);
//Cv0-=((v1<<4)+k0)^(v1+sum)^((v1>>5)+k1);
$z=$this->_add($z,-($this->_add(($y<<4),$this->a)^$this->_add($y,$sum)^$this->_add($this->_rshift($y,5),$this->b)));
$y=$this->_add($y,-($this->_add(($z<<4),$this->a)^$this->_add($z,$sum)^$this->_add($this->_rshift($z,5),$this->b)));
$sum=$this->_add($sum,-$delta);
}

$w[0]=$y;
$w[1]=$z;
}
privatefunction_resize(&$data,$size,$nonull=false){
$n=strlen($data);
$nmod=$n%$size;
if(0==$nmod)
$nmod=$size;

if($nmod>0){
if($nonull){
for($i=$n;$i<$n-$nmod+$size;++$i){
$data[$i]=$data[$i%$n];
}
}else{
for($i=$n;$i<$n-$nmod+$size;++$i){
$data[$i]=chr(0);
}
}
}
return$n;
}
privatefunction_hex2bin($str){
$len=strlen($str);
returnpack('H'.$len,$str);
}
privatefunction_str2long($start,&$data,&$data_long){
$n=strlen($data);

$tmp=unpack('N*',$data);
$j=$start;

foreach($tmpas$value)
$data_long[$j++]=$value;

return$j;
}
privatefunction_long2str($l){
returnpack('N',$l);
}


privatefunction_rshift($integer,$n){
//convertto32bits
if(0xffffffff<$integer||-0xffffffff>$integer){
$integer=fmod($integer,0xffffffff+1);
}

//converttounsignedinteger
if(0x7fffffff<$integer){
$integer-=0xffffffff+1.0;
}elseif(-0x80000000>$integer){
$integer+=0xffffffff+1.0;
}

//dorightshift
if(0>$integer){
$integer&=0x7fffffff;//removesignbitbeforeshift
$integer>>=$n;//rightshift
$integer|=1<<(31-$n);//setshiftedsignbit
}else{
$integer>>=$n;//usenormalrightshift
}

return$integer;
}
privatefunction_add($i1,$i2){
$result=0.0;

foreach(func_get_args()as$value){
//removesignifnecessary
if(0.0>$value){
$value-=1.0+0xffffffff;
}

$result+=$value;
}

//convertto32bits
if(0xffffffff<$result||-0xffffffff>$result){
$result=fmod($result,0xffffffff+1);
}

//converttosignedinteger
if(0x7fffffff<$result){
$result-=0xffffffff+1.0;
}elseif(-0x80000000>$result){
$result+=0xffffffff+1.0;
}

return$result;
}

//}}}
}
?>

上面的是TEA的演算法,XTEA的演算法為:


#include <stdint.h>


void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const k[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 + k[sum & 3]);

sum += delta;

v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);

}

v[0]=v0; v[1]=v1;

}


void decipher(unsigned int num_rounds, uint32_t v[2], uint32_t const k[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 &#8722;= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);

sum &#8722;= delta;

v0 &#8722;= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);

}

v[0]=v0; v[1]=v1;

}


那PHP中只需要把運算的位置改下就OK


private function _teaencipherLong($y, $z, &$w, &$k) {

$sum = ( integer ) 0;

$delta = 0x9E3779B9;

$n = ( integer ) $this->n_iter;

while ( $n -- > 0 ) {

$y = $this->_add ( $y, $this->_add ( $z << 4 ^ $this->_rshift ( $z, 5 ), $z ) ^ $this->_add ( $sum, $k [$sum & 3] ) );

$sum = $this->_add ( $sum, $delta );

$z = $this->_add ( $z, $this->_add ( $y << 4 ^ $this->_rshift ( $y, 5 ), $y ) ^ $this->_add ( $sum, $k [$this->_rshift ( $sum, 11 ) & 3] ) );

}

$w [0] = $y;

$w [1] = $z;

}

private function _decipherLong($y, $z, &$w, &$k) {

// sum = delta<<5, in general sum = delta * n

$sum = 0xC6EF3720;

$delta = 0x9E3779B9;

$n = ( integer ) $this->n_iter;

while ( $n -- > 0 ) {

$z = $this->_add ( $z, - ($this->_add ( $y << 4 ^ $this->_rshift ( $y, 5 ), $y ) ^ $this->_add ( $sum, $k [$this->_rshift ( $sum, 11 ) & 3] )) );

$sum = $this->_add ( $sum, - $delta );

$y = $this->_add ( $y, - ($this->_add ( $z << 4 ^ $this->_rshift ( $z, 5 ), $z ) ^ $this->_add ( $sum, $k [$sum & 3] )) );

}

$w [0] = $y;

$w [1] = $z;

❻ Tea演算法的疑問

我想你能搜到TEA演算法的源碼吧,不管如何,我也貼一份, encrypt是加密,decrpty是解密。 第一個輸入參數是要被加密/解密的信息,是64bit,也就是一個int32數組,數組是兩個元素。 第二個參數是128bit的密鑰,也就是4個元素的int32數組。密鑰你可以理解成密碼,只不過在TEA演算法中,要求密鑰必須是128bit。
所以,TEA演算法一次加密/解密64bit信息,如果你要加密/解密的信息長於64bit,那你要分多次進行,如果小於64bit,比如你只想加密一個數字 123,那你應該把這個信息補全到64bit,比如前32bit是你要加密的數字,後32位隨便是什麼。

看一下我下面的例子, 我用 "0123456789abcdef" 這個字元串(剛好16個字元,128bit)作為密鑰,要加密的信息是 {123, 321} 兩個整數 (剛好64bit)。然後列印出加密後得到的內容,以及解密後得到的內容(解密後得到的內容就合加密前一樣,是{123,321})

另外,你可能會注意到 加密解密時候用到的 delta=0x9e3779b9; 這個數字的得來是 2^32 除以一個常數,這個常數就是傳說中的黃金比例 1.6180339887。

我不了解QQ是如何使用TEA的,但是無非就是將用戶密碼根據一定的方式轉換成 128bit的密鑰,然後再應用 encrypt/decrypt 函數來對收發數據進行加密/解密,一次處理64bit,和我的例子沒有什麼實質性的區別。

#include <stdio.h>
#include <stdint.h>
#include <string.h>
void encrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schele constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i < 32; i++) { /* basic cycle start */
sum += delta;
v0 += ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
v1 += ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
} /* end cycle */
v[0]=v0; v[1]=v1;
}

void decrypt (uint32_t* v, uint32_t* k) {
uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i; /* set up */
uint32_t delta=0x9e3779b9; /* a key schele constant */
uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; /* cache key */
for (i=0; i<32; i++) { /* basic cycle start */
v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
sum -= delta;
} /* end cycle */
v[0]=v0; v[1]=v1;
}

int main()
{
const char *passwd = "0123456789abcdef";
uint32_t value[2] = {123, 321};
uint32_t key[4];
char *p = NULL;

memcpy(key, passwd, sizeof(key));

encrypt(value, key);

printf("After encrypt {%u, %u}\n", value[0], value[1]);

decrypt(value, key);

printf("After descrpt {%u, %u}\n", value[0], value[1]);

return 0;
}

密鑰不是胡編亂造的,密鑰就相當於密碼,不同的人會有不同的密碼。但是每個人的密碼長度可能與加密演算法需要的密碼長度不同,這樣就要按照一定的規則將用戶密碼變成符合要求的密鑰,比如用 MD5演算法 就可以將任意字元串轉換成128bit的密鑰,然後就可以應用 TEA 來加密數據。要破解這樣的數據,除非你知道那個128bit的密鑰,也就是只有你知道用戶本身的密碼是什麼,你才能得到128bit的密鑰,你才能解密數據。

我的例子里的密鑰只是隨便寫了一個舉例用的,你可以改成任何你想要的內容。

❼ TEA加密演算法的介紹

TEA演算法由劍橋大學計算機實驗室的David Wheeler和Roger Needham於1994年發明。它是一種分組密碼演算法,其明文密文塊為64比特,密鑰長度為128比特。TEA演算法利用不斷增加的Delta(黃金分割率)值作為變化,使得每輪的加密是不同,該加密演算法的迭代次數可以改變,建議的迭代次數為32輪。

❽ tea演算法的介紹

在安全學領域,TEA(Tiny Encryption Algorithm)是一種分組加密演算法,它的實現非常簡單,通常只需要很精短的幾行代碼。TEA 演算法最初是由劍橋計算機實驗室的 David Wheeler 和 Roger Needham 在 1994 年設計的。TEA演算法使用64位的明文分組和128位的密鑰,它使用Feistel分組加密框架,需要進行 64 輪迭代,盡管作者認為 32 輪已經足夠了。該演算法使用了一個神秘常數δ作為倍數,它來源於黃金比率,以保證每一輪加密都不相同。但δ的精確值似乎並不重要,這里 TEA 把它定義為 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9)。之後 TEA 演算法被發現存在缺陷,作為回應,設計者提出了一個 TEA 的升級版本——XTEA(有時也被稱為「tean」)。XTEA 跟 TEA 使用了相同的簡單運算,但它採用了截然不同的順序,為了阻止密鑰表攻擊,四個子密鑰(在加密過程中,原 128 位的密鑰被拆分為 4 個 32 位的子密鑰)採用了一種不太正規的方式進行混合,但速度更慢了。

❾ 什麼是TEA演算法

TEA演算法被廣泛地應用於計算機數據加密領域,OICQ的數據安全採用了TEA演算法。本文討論了TEA的演算法的原理及實現,並揭示了QQ中該演算法的應用,本文是靈鑰科技公司(www.panakes.com)在即時通信密碼研究公開的第一篇論文,今後我們將陸續發表相關的論文及相應的產品。

TEA演算法簡介
TEA演算法是由劍橋大學計算機實驗室的DavidWheeler和RogerNeedham於1994年發明.TEA是TinyEncryptionAlgorithm的縮寫。特點是加密速度極快,高速高效,但是抗差分攻擊能力差。

TEA加密演算法是一種分組密碼演算法,其明文密文塊64比特(8位元組),密鑰長度128比特(16位元組)。TEA加密演算法的迭代次數可以改變,建議的迭代次數為32輪,盡管演算法的發明人強調加密16輪就很充分了。兩個TEAFeistel周期算為一輪。圖1示例了TEA一輪的加密流程。

以下示例了TEA的C語言加密演算法,TEA的解密演算法與加密演算法類似。

#defineTEA_ROUNDS0x20
#defineTEA_DELTA0x9E3779B9
#defineTEA_SUM0xE3779B90

voidtiny_encrypt(unsignedlong*constv,unsignedlong*constw,
constunsignedlong*constk)
{
registerunsignedlong
y=v[0],
z=v[1],
a=k[0],
b=k[1],
c=k[2],
d=k[3],
n=TEA_ROUNDS,
sum=0,
delta=TEA_DELTA;

while(n-->0){
sum+=delta;
y+=(z<<4)+a^z+sum^(z>>5)+b;
z+=(y<<4)+c^y+sum^(y>>5)+d;
}
w[0]=y;
w[1]=z;
}

TEA演算法利用的不斷增加的(即源程序中的delta)值作為變化,,就是黃金分割率。它的作用是使得每輪的加密是不同。的准確值可能不太重要。但是在這里,它被初始化為

=0x9e3779b

QQ是如何利用TEA進行加密的?
TEA演算法被廣泛應用於QQ的數據加密中,QQ採用16輪的TEA演算法加密,在這時採取16輪加密時而不採取標準的32輪加密時為了減少驗證伺服器的壓力。QQ在數據加密前採用了密碼學中的常用的填充及交織技術,減少加密數據的相關性,增加破譯者的破解難度。

下表列出了QQ應用TEA演算法幾個方面

序號
應用
相關文件

1
通訊報文的加密/解密

2
消息記錄的加密/解密
MsgEx.db

3
本地消息密碼、首次登錄時間、提示內容驗證密碼
Matrix.db

4
消息備份文件
*.bak

QQ的TEA演算法源程序分析
QQ在進行TEA加密前採用ntohl函數對原文數據和加密密鑰進行了變換,從網路位元組順序轉換位主機位元組順序進行加密後,再通過htonl函數將數據轉換為網路位元組順序的數據。

為什麼要這樣做呢?因為不同的計算機使用不同的位元組順序存儲數據。因此任何從Winsock函數對IP地址和埠號的引用和傳給Winsock函數的IP地址和埠號均時按照網路順序組織的。

為防止分析者分析出QQ是採用TEA加密演算法的,程序的設計者採用了subeax,61C88647h指令,而不採用Addeax9e3779b9h指令。因為分析者只需要判斷9e3779b9h(即是我們前面提的黃金分割率的值)就知道採用了TEA加密演算法。

sub_409A43procnear;CODEXREF:sub_409B8C+AEp
;sub_409B8C+109p...

var_10=dwordptr-10h
var_C=dwordptr-0Ch
var_8=dwordptr-8
var_4=dwordptr-4
arg_0=dwordptr8
arg_4=dwordptr0Ch
arg_8=dwordptr10h

pushebp
movebp,esp
subesp,10h
pushebx
pushesi
movesi,[ebp+arg_0]
pushedi
pushdwordptr[esi];netlong
callntohl
pushdwordptr[esi+4];netlong
movedi,eax;y
callntohl
movebx,eax;z
moveax,[ebp+arg_4]
leaecx,[ebp+var_10]
leaesi,[ebp+var_10]
subeax,ecx
mov[ebp+arg_0],4
mov[ebp+arg_4],eax
jmpshortloc_409A7C
;哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪哪?
.text:00409A79
loc_409A79:;CODEXREF:sub_409A43+49j
moveax,[ebp+arg_4]

loc_409A7C:;CODEXREF:sub_409A43+34j
pushdwordptr[eax+esi];netlong
callntohl;對k[0],k[1],k[2],k[3]進行ntohl變化,
mov[esi],eax
addesi,4
dec[ebp+arg_0]
jnzshortloc_409A79

push10h;做十六輪TEA運算
xoreax,eax
popecx

loc_409A93:;CODEXREF:sub_409A43+88j
movedx,ebx
movesi,ebx
shredx,5;z>>5
addedx,[ebp+var_C];z>>5+k[1]
subeax,61C88647h;sum=sum+deltadelta:0x9e3779b9
shlesi,4;z<<4
addesi,[ebp+var_10];z<<4+k[0]
xoredx,esi;(z>>5+k[1])^(z<<4+k[0])
leaesi,[eax+ebx];sum+z
xoredx,esi;(z<<4+k[0])^(sum+z)^(z>>5+k[1])
addedi,edx;y+=(z<<4+k[0])^(sum+z)^(z>>5+k[1])

movedx,edi
movesi,edi
shredx,5;y>>5
addedx,[ebp+var_4];y>>5+k[3]
shlesi,4;y<<4
addesi,[ebp+var_8];y<<4+k[2]
xoredx,esi;(y>>5+k[3])^(y<<4+k[2])
leaesi,[eax+edi];(sum+y)
xoredx,esi;(y<<4+k[2])^(sum+y)^(y>>5+k[3])
addebx,edx;z+=(y<<4+k[2])^(sum+y)^(y>>5+k[3])
dececx
jnzshortloc_409A93

pushedi;hostlong
callhtonl
movesi,[ebp+arg_8]
pushebx;hostlong
mov[esi],eax;加密結果
callhtonl
mov[esi+4],eax;加密結果
popedi
popesi
popebx
leave
retn
sub_409A43endp

結論
作為一種分組加密演算法,TEA加密演算法在其發展的過程中,目前出現了幾種針對TEA演算法設計的缺陷攻擊方法,使得原有的TEA加密演算法變得不安全,在過去的十幾年中,TEA演算法進行了若干次的改進,歷經XTEA,BlockTEA,XXTEA幾個版本。目前最新的演算法是XXTEA。

QQ採用了最初的TEA演算法做其核心的加密演算法,QQ在採用TEA演算法時採用了16輪的加密,其加密復雜度比32輪減了許多。利用TEA演算法的設計缺陷,使得快速破解QQ密碼成為可能。

值得一提的QQ在利用TEA演算法做加密時,採用了交織及隨機填充隨機數的技術,增加了密碼分析者分析難度,從一定程度上保護了信息的安全。

更多信息請訪問www.panakes.com

TEA(Tiny Encryption Algorithm) 是一種優秀的數據加密演算法,雖然它比 DES(Data Encryption Standard) 要簡單得多, 但有很強的抗差分分析能力,加密速度也比 DES 快得多,而且對 64 位數據加密的密鑰長達 128 位,安全性相當好。 下面的程序來自盧開澄《計算機密碼學》(清華大學出版社)。

補充:為了使這段程序更加實用,我將其整理為幾個單元, 分別用於 Delphi 和 C++Builder 。包括對數據流 TMemoryStream 和字元串的加密/解密功能, 對字元串的加密/解密還通過 Base64 編碼/解碼,保持加密後的字元串仍為字元串。

// v[2] : 64bit data, k[4] : 128bit key

void encipher( unsigned long * const v, const unsigned long * const k )
{
register unsigned long y = v[0], z = v[1], sum = 0, delta = 0x9E3779B9,
a = k[0], b = k[1], c = k[2], d = k[3], n = 32;

while ( n-- > 0 )
{
sum += delta;
y += ( z << 4 ) + a ^ z + sum ^ ( z >> 5 ) + b;
z += ( y << 4 ) + c ^ y + sum ^ ( y >> 5 ) + d;
}
v[0] = y;
v[1] = z;
}

void decipher( unsigned long * const v, const unsigned long * const k )
{
register unsigned long y = v[0], z = v[1], sum = 0xC6EF3720, delta = 0x9E3779B9,
a = k[0], b = k[1], c = k[2], d = k[3], n = 32;

// sum = delta << 5, in general sum = delta * n
while ( n-- > 0 )
{
z -= ( y << 4 ) + c ^ y + sum ^ ( y >> 5 ) + d;
y -= ( z << 4 ) + a ^ z + sum ^ ( z >> 5 ) + b;
sum -= delta;
}
v[0] = y;
v[1] = z;
}

閱讀全文

與tea演算法詳解相關的資料

熱點內容
華為筆記本電腦怎麼安裝抖音app 瀏覽:412
阿里雲國際版試用的伺服器怎麼搞 瀏覽:895
java正則表達式工具 瀏覽:160
oa伺服器怎麼設置ftp 瀏覽:10
安卓如何安裝obb 瀏覽:442
QQ聊天記錄journal文件夾 瀏覽:118
蘋果公司雲伺服器地址 瀏覽:85
加密記事本手機 瀏覽:437
汽車壓縮機變頻閥 瀏覽:95
域外伺服器是什麼意思 瀏覽:639
大眾點評伺服器怎麼老卡頓 瀏覽:556
javavector與list的區別 瀏覽:316
java初始化類數組 瀏覽:303
java字元串轉換成json對象 瀏覽:648
android非阻塞socket 瀏覽:358
編譯系統概念 瀏覽:452
天眼通app能做什麼 瀏覽:557
魅族手機怎麼加密圖庫 瀏覽:8
rpa編譯器 瀏覽:572
車載雲伺服器記錄 瀏覽:740