TEA演算法解析
阿新 • • 發佈:2020-10-20
目錄
輪迭代,儘管作者認為 32 輪已經足夠了。該演算法使用了一個神祕常數δ作為倍數,它來源於黃金比率,以保證每一輪加密都不相同。但δ的精確值似乎並不重要,這裡 TEA 把它定義為 δ=「(√5 - 1)231」(也就是程式中的 0×9E3779B9)。
之後 TEA 演算法被發現存在缺陷,作為迴應,設計者提出了一個 TEA 的升級版本——XTEA(有時也被稱為“tean”)。XTEA 跟 TEA 使用了相同的簡單運算,但它採用了截然不同的順序,為了阻止金鑰表攻擊,四個子金鑰(在加密過程中,原 128 位的金鑰被拆分為 4 個 32 位的子金鑰)採用了一種不太正規的方式進行混合,但速度更慢了
演算法之TEA
一丶TEA簡介
"TEA" 的全稱為"Tiny Encryption Algorithm" 是1994年由英國劍橋大學的David j.wheeler發明的.
TEA演算法也算是微型加密演算法
其加密流程如下
在安全學領域,TEA(Tiny Encryption Algorithm)是一種分組加密演算法,它的實現非常簡單,通常只需要很精短的幾行程式碼。TEA 演算法最初是由劍橋計算機實驗室的 David Wheeler 和 Roger Needham 在 1994 年設計的。
TEA演算法使用64位的明文分組和128位的金鑰,它使用Feistel分組加密框架,需要進行 64
之後 TEA 演算法被發現存在缺陷,作為迴應,設計者提出了一個 TEA 的升級版本——XTEA(有時也被稱為“tean”)。XTEA 跟 TEA 使用了相同的簡單運算,但它採用了截然不同的順序,為了阻止金鑰表攻擊,四個子金鑰(在加密過程中,原 128 位的金鑰被拆分為 4 個 32 位的子金鑰)採用了一種不太正規的方式進行混合,但速度更慢了
二丶加密解密程式碼演示
加密函式:
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; //總共加密32輪 for (int i = 0; i < 32; i++) { sum += delta; 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; }
其實這道題是在做CTF的時候遇到的,弄了半天百思不得其解最終搞出來了,發現其實是TEA演算法.
說一下解密的思路吧.
x +=xxx
y+=xxx 這兩個公司總共是執行了32輪,可以記做為
(x+=xxx)32
(y+=xxx)32
那麼解密的時候肯定也是執行32輪,每次遞減,且順序變換過來
(y-=xxx)
(x-=xxx)
其中這裡的xxx就是異或的公式,根據其特性我們不需要改公式中的內容.我們可以看做是 a ^ b ^ c 反過來
c ^ b ^ a 是一樣的.
既然倒過來了.我們的變數(黃金分割)也需要倒過來.
所以解密演算法如下
void Decrypt(long* EntryData, long* Key)
{
//分別加密陣列中的前四個位元組與後4個位元組,4個位元組為一組每次加密兩組
unsigned long x = EntryData[0];
unsigned long y = EntryData[1];
unsigned long sum = 0;
unsigned long delta = 0x9E3779B9;
sum = delta << 5; //注意這裡,sum = 32輪之後的值,如果你是在加密函式內部寫解密就不需要這個移位
//總共加密32輪
for (int i = 0; i < 32; i++)
{
y -= ((x << 4) + Key[2]) ^ (x + sum) ^ ((x >> 5) + Key[3]);
x -= ((y << 4) + Key[0]) ^ (y + sum) ^ ((y >> 5) + Key[1]);
sum -= delta;
}
//最後加密的結果重新寫入到陣列中
EntryData[0] = x;
EntryData[1] = y;
}
最終實現結果
int main()
{
long Data[3] = { 0x44434241,0x48474645,0x0 };
printf("待加密的數值 = %s\r\n", (char*)Data);
long key[4] = { 0x11223344,0x55667788,0x99AABBCC,0xDDEEFF11 };
//Encrypt每次只是加密4位元組陣列中的兩組(也就是每次加密8個位元組) 如果你資料多.可以來個for迴圈來迴圈加密,但是Entrypt內部還有32次迴圈,所以速度上還是會有點影響.
Encrypt(Data, key);
printf("加密後的數值 = %s\r\n", (char*)Data);
Decrypt(Data, key);
printf("解密後的數值 = %s\r\n", (char*)Data);
system("pause");
}
實現結果