導航:首頁 > 源碼編譯 > ctea演算法

ctea演算法

發布時間:2025-04-13 12:13:58

『壹』 什麼是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;
}

『貳』 1、 總結一下面向對象編程(OOP)的基本特徵。

面向對象三大特性:封裝,繼承,多態
面向對象(Object Oriented,縮寫為OO)是現代軟體技術的精髓。從早期的SmallTalk到如日中天的Java,都滲透著面向對象思想。
OO具有三大特性:封裝性、繼承性和多態性。想掌握面向對象思想,就必須深入理解
其三大特性。這里我盡量少談概念,只用一個生活中的例子和一段代碼來解釋它們。

1、封裝性(Encapsulation)
所謂封裝,就是將某些東西包裝和隱藏起來,讓外界無法直接使用,只能通過某些特定的方式才能訪問。OO將萬物都視為「對象」(Object),任何對象都具有特性和行為。我們將其特性稱為「成員變數」 (MemberVarible),將其行為稱之為「成員函數"(Member Function),被封裝的特性只能通過特定的行為去訪問。
大家都見過旅館里常用的一種茶葉吧,就是用紙袋把茶葉包裝起來再系是一根線。用的時候只需要將其放在水杯里泡就行。這樣的好處是不會將茶葉渣和茶垢弄的滿杯子都是。
好!這就是一個封裝的例子。
我們喝茶的目的是享受茶葉的香冽;所以茶葉的味道(Flavour)就是茶葉所具有的最
重要特性之一;可是我們無法直接享受它的清香,因為被外面的紙袋「封裝」起來了。唯一的辦法就是「泡」(Dilute),將茶袋扔在開水中泡,它的味道就出來了,融入水中。
如果我們把袋裝茶葉看作一個對象的話,它提供了成員變數Flavour和成員函數Dilute
。並且Flavour是私有(Private)的,我們不能直接把它吞進肚子去,而只能通過成員函
數Dilute才能享受Flavour。
下面用C++代碼來描述這個例子:
Class CTea
{
Private:
Cstring m_Flavour; //味道
Cstring m_Color; //顏色
...... //等等其它屬性
Private:
Void CTea(); //構造函數
Void ~CTea(); //析構函數
Public:
Cstring Dilute();//沏茶
...... //等等其它方法
}
Cstring CTea::Dilute()
{
//怎樣泡出味道來的代碼
}
這就是封裝。通過將對象的某些屬性聲明為Private隱藏起來,只能使用其提供的特定
方法去訪問。

2、繼承(Inheritance)
如果只是封裝,那麼非面向對象語言也能部分的做到。比如在C中,用結構(Struct)、
VB中用自定義類型(Type)也能封裝一些變數。
OO最有吸引力的特性是繼承。通俗的說後代具有祖先的某些特點就叫繼承,當然後代還可以具有自己獨有的特徵。舉個例子吧,菜刀。
菜刀(cutlery)是鋼(Steel)做的,鋼是一種金屬(Metal),金屬則是大千世界裡的一種物質(Substance)。所以菜刀的一些特性可以追溯到物質具有的一般屬性。正是因為這個道理,MFC中所有類均從CObject繼承而來。
這就是繼承。菜刀直接繼承了鋼的特性,鋼又繼承了金屬的特性,......下面的代碼描
述了這種復雜而有獨特的繼承關系:
Class CSubstance
{
Private:
int m_color;
void CSubstance();
void ~CSubstance();
//......(我是學文科的,具體屬性說不上來)
}
Class CMetal:Public CSubstance
{
void CMetal();
void ~CMetal();
//......
}
Class CSteel:Public CMetal
{
void CSteel();
void ~CSteel();
//......
}
Class CCutlery:Public CSteel
{
private:
Cstring m_Blade;
void CCutlery();
void ~CCutlery();
//......
Public:
void Cut();
}
這里,CSubstance被稱為基類(Base class),其它被稱為衍生類(Derived class)。衍生類與基類是「Is kind of」的關系。子類與其祖先類之間復雜的函數調用關系不在本文討論之列。
繼承是一種樹狀的層次關系。子類在繼承祖先類的成員變數和成員函數的同時也可以
定義自己的成員變數和成員函數。比如,Metal 除了繼承了Substance的一般特性外,還具有自己的屬性諸如可延展性;CCutlery在繼承CSteel的特性後還具有自己的成員諸如「刀刃」(Blade)、「鋒利」(Sharpness)、行為有如「切」(Cut)等。
面向對象技術是對現實生活的抽象,你可以用生活中的經驗去思考程序設計的邏輯。

3、多態性(Polymorphism)
討論多態之前先要明白什麼是「虛擬」(Virtual)。C++/MFC就是用虛擬這種方式實現多態的。為什麼「虛擬」這個概念?看下邊的例子:
Class Cincect //昆蟲類
{
private:
int m_foot; //腳的數量
...... //其它成員變數
private:
void Cincect();
void ~Cincect();
public:
void Bite()//咬人
{
...... //怎樣咬人的代碼,比如張開嘴啃
}
}
我把Bite(咬)這個動作在基類中定義為一般化動作。可是,不是所有昆蟲咬
人的方法都一樣(況且還有的根本就不咬人呢,比如蜻蜓),比如蚊子是用嘴那個
吸管叮人而螞蟻是用嘴去夾。
從昆蟲這個類別衍生出以下兩個類別:Cant(螞蟻)、Cmosquito(蚊子)。
class Cant :public Cincect //螞蟻類
{
......
}
class Cmosquito :public Cincect //蚊子類
{
......
}
它們都繼承了Cincect的所有成員,當然也繼承了Bite()這個動作。現在就有問題了:
同樣繼承自昆蟲,當我們使用Bite()這個動作時怎麼才能區分螞蟻和蚊子各自的獨有的咬人方式呢?
方法之一是用「::」符號指明具體引用的是那一個,但這樣明顯失去了靈活性;
另一種方法就是「虛擬」。使用關鍵字virtual將Bite()聲明為虛擬函數,然後在每個
衍生類中重新定義,描述它們各自的咬人方法,調用的時候也不會都一種結果啦。於是上邊的例子可以改寫為:

Class Cincect //昆蟲類
{
private:
int m_foot; //腳的數量
...... //其它成員變數
private:
void Cincect();
void ~Cincect();
public:
virtual Bite(){}//咬人,但我們只聲明這個成員函數,
//卻讓它什麼動作都不做,讓衍生類自己去定
//義各自的咬人方法
}
class Cant :public Cincect //螞蟻類
{
......
virtual Bite();
}
Cant::Bite()
{
...... //螞蟻具體的咬人方式
}

class Cmosquito :public Cincect //蚊子類
{
......
virtual Bite();
}
Cmosquito::Bite()
{
...... //蚊子具體的咬人方式
}
所以,虛擬的目的是只在基類中將一般化動作聲明一個成員函數的原型而不做
具體定義,讓衍生類自己去定義。
這就是面向對象的特徵之三:多態性。基類的同一個成員在不同的衍生類中可以具
有不同的形態,更好地抽象和描述大千世界中的諸多「對象」。

1.了解什麼是多態性

2.如何定義一個虛方法

3.如何重載一個虛方法

4.如何在程序中運用多態性

面向對象程序設計中的另外一個重要概念是多態性。在運行時,可以通過指向基類的指針,來調用實現派生類中的方法。 可以把一組對象放到一個數組中,然後調用它們的方法,在這種場合下,多態性作用就體現出來了,這些對象不必是相同類型的對象。當然,如果它們都繼承自某個類,你可以把這些派生類,都放到一個數組中。 如果這些對象都有同名方法,就可以調用每個對象的同名方法。本節課將向你介紹如何完成這些事情。

1.清單9-1. 帶有虛方法的基類:DrawingObject.cs

using System;
public class DrawingObject
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}

說明

清單9-1 定義了DrawingObject類。這是個可以讓其他對象繼承的基類。該類有一個名為Draw()的方法。Draw()方法帶有一個virtual修飾符,該修飾符表明:該基類的派生類可以重載該方法。DrawingObject類的 Draw()方法完成如下事情:輸出語句"I'm just a generic drawing object."到控制台。

2.清單9-2. 帶有重載方法的派生類:Line.cs, Circle.cs, and Square.cs

using System;
public class Line : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}

public class Circle : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Circle.");
}
}

public class Square : DrawingObject
{
public override void Draw()
{
Console.WriteLine("I'm a Square.");
}
}

說明

清單9-2定義了三個類。這三個類都派生自DrawingObject類。每個類都有一個同名Draw()方法,這些Draw()方法中的每一個都有一個重載修飾符。重載修飾符可讓該方法在運行時重載其基類的虛方法,實現這個功能的條件是:通過基類類型的指針變數來引用該類。

3.清單9-3. 實現多態性的程序:DrawDemo.cs

using System;
public class DrawDemo
{
public static int Main(string[] args)
{
DrawingObject[] dObj = new DrawingObject[4];
dObj[0] = new Line();
dObj[1] = new Circle();
dObj[2] = new Square();
dObj[3] = new DrawingObject();
foreach (DrawingObject drawObj in dObj)
{
drawObj.Draw();
}
return 0;
}
}

說明

清單9-3演示了多態性的實現,該程序使用了在清單 9-1 和清單9-2中定義的類。在DrawDemo類中的Main()方法中,創建了一個數組, 數組元素是DrawingObject 類的對象。該數組名為dObj,是由四個DrawingObject類型的對象組成。

接下來, 初始化dObj數組, 由於Line, Circle和Square類都是DrawingObject類的派生類,所以這些類可以作為dObj數組元素的類型。 如果C#沒有這種功能,你得為每個類創建一個數組。繼承的性質可以讓派生對象當作基類成員一樣用,這樣就節省了編程工作量。

一旦數組初始化之後,接著是執行foreach循環,尋找數組中的每個元素。在每次循環中, dObj 數組的每個元素(對象)調用其Draw()方法。多態性體現在:在運行時,各自調用每個對象的Draw()方法。盡管dObj 數組中的引用對象類型是DrawingObject,這並不影響派生類重載DrawingObject 類的虛方法Draw()。 在dObj 數組中,通過指向DrawingObject 基類的指針來調用派生類中的重載的Draw()方法。

輸出結果是:

I'm a Line.
I'm a Circle.
I'm a Square.
I'm just a generic drawing object.

在DrawDemo 程序中,調用了每個派生類的重載的Draw()方法。 最後一行中,執行的是DrawingObject類的虛方法Draw()。這是因為運行到最後,數組的第四個元素是DrawingObject類的對象。

小結
現在對多態性有所了解之後,你可以在派生類中,實現一個重載基類虛方法的方法。虛方法和重載的派生類方法之間的關系就體現出C#的多態性。

閱讀全文

與ctea演算法相關的資料

熱點內容
pthreads安裝linux 瀏覽:272
androidfragment嵌套 瀏覽:276
單片機在線升級 瀏覽:115
程序員吃包子視頻 瀏覽:808
安卓為什麼不封app 瀏覽:465
電車租車app叫什麼 瀏覽:728
編程員英文 瀏覽:266
負載均衡伺服器如何部署項目 瀏覽:528
迷你世界的程序員怎麼獲取 瀏覽:367
洗澡楊絳pdf 瀏覽:218
程序員的詩詞大會 瀏覽:728
怎麼修改建行app名 瀏覽:815
雲終端怎麼加密 瀏覽:610
linuxxserver啟動 瀏覽:97
迅雷把文件分解加密 瀏覽:89
好玩友app怎麼查找游戲 瀏覽:870
互聯網公司java 瀏覽:527
為什麼能上網卻提示找不到伺服器 瀏覽:584
基於單片機的多功能門鈴 瀏覽:956
南昌微型往復活塞空氣壓縮機 瀏覽:143