Tea加密算法和XxTea加密算法

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
简介:

TEA(Tiny Encryption Algorithm)是一种小型的对称加密解密算法,支持128位密码,与BlowFish一样TEA每次只能加密/解密8字节数据。TEA特点是速度快、效率高,实现也非常简单。由于针对TEA的攻击不断出现,所以TEA也发展出几个版本,分别是XTEA、Block TEA和XXTEA。

TEA加密和解密时都使用一个常量值,这个常量值为0x9e3779b,这个值是近似黄金分割率,注意,有些编程人员为了避免在程序中直接出现"mov 变量,0x9e3779b",以免被破解者直接搜索0x9e3779b这个常数得知使用TEA算法,所以有时会使用"sub 变量,0x61C88647"代替"mov 变量,0x9e3779b",0x61C88647=-(0x9e3779b)。

TEA算法每一次可以操作64bit(8byte),采用128bit(16byte)作为key,算法采用迭代的形式,推荐的迭代轮数是64轮,最少32轮。

标准的16轮运算TEA,如果要改成标准的32轮运算TEA,只需修改code和decode中的n为32,并将decode中的delta左移4位改成左移5位即可。

C#的实现代码:

 

 
  1. public static class Tea  
  2.     {  
  3.  
  4.         public static byte[] Encrypt(byte[] data, byte[] key)  
  5.         {  
  6.  
  7.             byte[] dataBytes;  
  8.             if (data.Length % 2 == 0)  
  9.             {  
  10.                 datadataBytes = data;  
  11.  
  12.             }  
  13.             else  
  14.             {  
  15.                 dataBytes = new byte[data.Length + 1];  
  16.                 Array.Copy(data, 0, dataBytes, 0, data.Length);  
  17.                 dataBytes[data.Length] = 0x0;  
  18.  
  19.             }  
  20.             byte[] result = new byte[dataBytes.Length * 4];  
  21.             uint[] formattedKey = FormatKey(key);  
  22.             uint[] tempData = new uint[2];  
  23.             for (int i = 0; i < dataBytes.Length; i += 2)  
  24.             {  
  25.                 tempData[0] = dataBytes[i];  
  26.                 tempData[1] = dataBytes[i + 1];  
  27.                 code(tempData, formattedKey);  
  28.                 Array.Copy(ConvertUIntToByteArray(tempData[0]), 0, result, i * 4, 4);  
  29.                 Array.Copy(ConvertUIntToByteArray(tempData[1]), 0, result, i * 4 + 4, 4);  
  30.             }  
  31.             return result;  
  32.         }  
  33.  
  34.         public static byte[] Decrypt(byte[] data, byte[] key)  
  35.         {  
  36.             uint[] formattedKey = FormatKey(key);  
  37.             int x = 0;  
  38.             uint[] tempData = new uint[2];  
  39.             byte[] dataBytes = new byte[data.Length / 8 * 2];  
  40.             for (int i = 0; i < data.Length; i += 8)  
  41.             {  
  42.                 tempData[0] = ConvertByteArrayToUInt(data, i);  
  43.                 tempData[1] = ConvertByteArrayToUInt(data, i + 4);  
  44.                 decode(tempData, formattedKey);  
  45.                 dataBytes[x++] = (byte)tempData[0];  
  46.                 dataBytes[x++] = (byte)tempData[1];  
  47.             }  
  48.             //修剪添加的空字符  
  49.             if (dataBytes[dataBytes.Length - 1] == 0x0)  
  50.             {  
  51.                 byte[] result = new byte[dataBytes.Length - 1];  
  52.                 Array.Copy(dataBytes, 0, result, 0, dataBytes.Length - 1);  
  53.             }  
  54.             return dataBytes;  
  55.  
  56.         }  
  57.  
  58.         static uint[] FormatKey(byte[] key)  
  59.         {  
  60.             if (key.Length == 0)  
  61.                 throw new ArgumentException("Key must be between 1 and 16 characters in length");  
  62.             byte[] refineKey = new byte[16];  
  63.             if (key.Length < 16)  
  64.             {  
  65.                 Array.Copy(key, 0, refineKey, 0, key.Length);  
  66.                 for (int k = key.Length; k < 16; k++)  
  67.                 {  
  68.                     refineKey[k] = 0x20;  
  69.                 }  
  70.             }  
  71.             else  
  72.             {  
  73.                 Array.Copy(key, 0, refineKey, 0, 16);  
  74.             }  
  75.             uint[] formattedKey = new uint[4];  
  76.             int j = 0;  
  77.             for (int i = 0; i < refineKey.Length; i += 4)  
  78.                 formattedKey[j++] = ConvertByteArrayToUInt(refineKey, i);  
  79.             return formattedKey;  
  80.         }  
  81.         #region Tea Algorithm  
  82.         static void code(uint[] v, uint[] k)  
  83.         {  
  84.             uint y = v[0];  
  85.             uint z = v[1];  
  86.             uint sum = 0;  
  87.             uint delta = 0x9e3779b9;  
  88.             uint n = 16;  
  89.             while (n-- > 0)  
  90.             {  
  91.                 sum += delta;  
  92.                 y += (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];  
  93.                 z += (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];  
  94.             }  
  95.             v[0] = y;  
  96.             v[1] = z;  
  97.         }  
  98.  
  99.         static void decode(uint[] v, uint[] k)  
  100.         {  
  101.             uint n = 16;  
  102.             uint sum;  
  103.             uint y = v[0];  
  104.             uint z = v[1];  
  105.             uint delta = 0x9e3779b9;  
  106.             /*  
  107.             * 由于进行16轮运算,所以将delta左移4位,减16次后刚好为0.  
  108.             */  
  109.             sum = delta << 4;  
  110.             while (n-- > 0)  
  111.             {  
  112.                 z -= (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];  
  113.                 y -= (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];  
  114.                 sum -delta;  
  115.             }  
  116.             v[0] = y;  
  117.             v[1] = z;  
  118.         }  
  119.         #endregion  
  120.  
  121.         private static byte[] ConvertUIntToByteArray(uint v)  
  122.         {  
  123.             byte[] result = new byte[4];  
  124.             result[0] = (byte)(v & 0xFF);  
  125.             result[1] = (byte)((v >> 8) & 0xFF);  
  126.             result[2] = (byte)((v >> 16) & 0xFF);  
  127.             result[3] = (byte)((v >> 24) & 0xFF);  
  128.             return result;  
  129.         }  
  130.  
  131.         private static uint ConvertByteArrayToUInt(byte[] v, int offset)  
  132.         {  
  133.             if (offset + 4 > v.Length) return 0;  
  134.             uint output;  
  135.             output = (uint)v[offset];  
  136.             output |= (uint)(v[offset + 1] << 8);  
  137.             output |= (uint)(v[offset + 2] << 16);  
  138.             output |= (uint)(v[offset + 3] << 24);  
  139.             return output;  
  140.         }  
  141.     } 

 XTEA 跟 TEA 使用了相同的简单运算,但它采用了截然不同的顺序,为了阻止密钥表攻击,四个子密钥(在加密过程中,原 128 位的密钥被拆分为 4 个 32 位的子密钥)采用了一种不太正规的方式进行混合,但速度更慢了。在跟描述 XTEA 算法的同一份报告中,还介绍了另外一种被称为 Block TEA 算法的变种,它可以对 32 位大小任意倍数的变量块进行操作。该算法将 XTEA 轮循函数依次应用于块中的每个字,并且将它附加于它的邻字。该操作重复多少轮依赖于块的大小,但至少需要 6 轮。该方法的优势在于它无需操作模式(CBC,OFB,CFB 等),密钥可直接用于信息。对于长的信息它可能比 XTEA 更有效率。在 1998 年,Markku-Juhani Saarinen 给出了一个可有效攻击 Block TEA 算法的代码,但之后很快 David J. Wheeler 和 Roger M. Needham 就给出了 Block TEA 算法的修订版,这个算法被称为 XXTEA。XXTEA 使用跟 Block TEA 相似的结构,但在处理块中每个字时利用了相邻字。它利用一个更复杂的 MX 函数代替了 XTEA 轮循函数,MX 使用 2 个输入量。

  如果加密字符串长度不是 4 的整数倍,则这些实现的在加密后无法真正还原,还原以后的字符串实际上与原字符串不相等,而是后面多了一些 \0 的字符,或者少了一些 \0 的字符。原因在于 XXTEA 算法只定义了如何对 32 位的信息块数组(实际上是 32 位无符号整数数组)进行加密,而并没有定义如何来将字符串编码为这种数组。而现有的实现中在将字符串编码为整数数组时,都丢失了字符串长度信息,因此还原出现了问题。
C#的实现代码
 
  1. using System;  
  2.  
  3. class XXTEA  
  4. {  
  5.     public static Byte[] Encrypt(Byte[] Data, Byte[] Key)  
  6.     {  
  7.         if (Data.Length == 0)  
  8.         {  
  9.             return Data;  
  10.         }  
  11.         return ToByteArray(Encrypt(ToUInt32Array(Data, true), ToUInt32Array(Key, false)), false);  
  12.     }  
  13.     public static Byte[] Decrypt(Byte[] Data, Byte[] Key)  
  14.     {  
  15.         if (Data.Length == 0)  
  16.         {  
  17.             return Data;  
  18.         }  
  19.         return ToByteArray(Decrypt(ToUInt32Array(Data, false), ToUInt32Array(Key, false)), true);  
  20.     }  
  21.  
  22.     public static UInt32[] Encrypt(UInt32[] v, UInt32[] k)  
  23.     {  
  24.         Int32 n = v.Length - 1;  
  25.         if (n < 1)  
  26.         {  
  27.             return v;  
  28.         }  
  29.         if (k.Length < 4)  
  30.         {  
  31.             UInt32[] Key = new UInt32[4];  
  32.             k.CopyTo(Key, 0);  
  33.             k = Key;  
  34.         }  
  35.         UInt32 z = v[n], y = v[0], delta = 0x9E3779B9sum = 0, e;  
  36.         Int32 p, q = 6 + 52 / (n + 1);  
  37.         while (q-- > 0)  
  38.         {  
  39.             sum = unchecked(sum + delta);  
  40.             e = sum >> 2 & 3;  
  41.             for (p = 0; p < n; p++)  
  42.             {  
  43.                 y = v[p + 1];  
  44.                 z = unchecked(v[p] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));  
  45.             }  
  46.             y = v[0];  
  47.             z = unchecked(v[n] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));  
  48.         }  
  49.         return v;  
  50.     }  
  51.     public static UInt32[] Decrypt(UInt32[] v, UInt32[] k)  
  52.     {  
  53.         Int32 n = v.Length - 1;  
  54.         if (n < 1)  
  55.         {  
  56.             return v;  
  57.         }  
  58.         if (k.Length < 4)  
  59.         {  
  60.             UInt32[] Key = new UInt32[4];  
  61.             k.CopyTo(Key, 0);  
  62.             k = Key;  
  63.         }  
  64.         UInt32 z = v[n], y = v[0], delta = 0x9E3779B9, sum, e;  
  65.         Int32 p, q = 6 + 52 / (n + 1);  
  66.         sum = unchecked((UInt32)(q * delta));  
  67.         while (sum != 0)  
  68.         {  
  69.             e = sum >> 2 & 3;  
  70.             for (p = n; p > 0; p--)  
  71.             {  
  72.                 z = v[p - 1];  
  73.                 y = unchecked(v[p] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));  
  74.             }  
  75.             z = v[n];  
  76.             y = unchecked(v[0] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));  
  77.             sum = unchecked(sum - delta);  
  78.         }  
  79.         return v;  
  80.     }  
  81.     private static UInt32[] ToUInt32Array(Byte[] Data, Boolean IncludeLength)  
  82.     {  
  83.         Int32 n = (((Data.Length & 3) == 0) ? (Data.Length >> 2) : ((Data.Length >> 2) + 1));  
  84.         UInt32[] Result;  
  85.         if (IncludeLength)  
  86.         {  
  87.             Result = new UInt32[n + 1];  
  88.             Result[n] = (UInt32)Data.Length;  
  89.         }  
  90.         else  
  91.         {  
  92.             Result = new UInt32[n];  
  93.         }  
  94.         n = Data.Length;  
  95.         for (Int32 i = 0; i < n; i++)  
  96.         {  
  97.             Result[i >> 2] |= (UInt32)Data[i] << ((i & 3) << 3);  
  98.         }  
  99.         return Result;  
  100.     }  
  101.     private static Byte[] ToByteArray(UInt32[] Data, Boolean IncludeLength)  
  102.     {  
  103.         Int32 n;  
  104.         if (IncludeLength)  
  105.         {  
  106.             n = (Int32)Data[Data.Length - 1];  
  107.         }  
  108.         else  
  109.         {  
  110.             n = Data.Length << 2;  
  111.         }  
  112.         Byte[] Result = new Byte[n];  
  113.         for (Int32 i = 0; i < n; i++)  
  114.         {  
  115.             Result[i] = (Byte)(Data[i >> 2] >> ((i & 3) << 3));  
  116.         }  
  117.         return Result;  
  118.     }  

 

本文转自linzheng 51CTO博客,原文链接:http://blog.51cto.com/linzheng/1078489


相关文章
|
3月前
|
算法 安全 数据安全/隐私保护
Android经典实战之常见的移动端加密算法和用kotlin进行AES-256加密和解密
本文介绍了移动端开发中常用的数据加密算法,包括对称加密(如 AES 和 DES)、非对称加密(如 RSA)、散列算法(如 SHA-256 和 MD5)及消息认证码(如 HMAC)。重点讲解了如何使用 Kotlin 实现 AES-256 的加密和解密,并提供了详细的代码示例。通过生成密钥、加密和解密数据等步骤,展示了如何在 Kotlin 项目中实现数据的安全加密。
111 1
|
3月前
|
算法 安全 数据安全/隐私保护
Android经典实战之常见的移动端加密算法和用kotlin进行AES-256加密和解密
本文介绍了移动端开发中常用的数据加密算法,包括对称加密(如 AES 和 DES)、非对称加密(如 RSA)、散列算法(如 SHA-256 和 MD5)及消息认证码(如 HMAC)。重点展示了如何使用 Kotlin 实现 AES-256 的加密和解密,提供了详细的代码示例。
72 2
|
3月前
|
算法 JavaScript 前端开发
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
国标非对称加密:RSA算法、非对称特征、js还原、jsencrypt和rsa模块解析
255 1
|
3月前
|
算法 JavaScript 前端开发
消息摘要算法:MD5加密
消息摘要算法:MD5加密
57 1
|
6天前
|
安全 算法 网络安全
网络防御的艺术:揭秘加密技术与安全意识的重要性
【10月更文挑战第30天】在数字化时代,网络安全已成为我们生活中不可或缺的部分。本文旨在揭示网络安全漏洞的成因,探讨如何通过加密技术和提升安全意识来构建坚固的网络防线。文章将深入分析常见的安全威胁,并分享实用的防护策略,帮助读者在日益复杂的网络环境中保持警觉和安全。
54 29
|
1天前
|
安全 网络安全 数据安全/隐私保护
网络安全的盾牌与剑:漏洞、加密与意识
【10月更文挑战第35天】在这个数字化不断深入的时代,网络安全成了保护我们数据和隐私的重要屏障。本文将深入浅出地探讨网络安全中的漏洞发现、加密技术的应用以及提升个人安全意识的重要性,旨在为读者提供一扇了解和防御网络威胁的窗口。从黑客如何利用漏洞发起攻击,到如何使用加密技术保护数据,再到为何培养良好的安全习惯对抵御网络犯罪至关重要,我们将一一解析。让我们携手构建一个更安全的网络环境。
|
1天前
|
SQL 安全 算法
网络安全与信息安全:漏洞、加密与意识的交织
【10月更文挑战第35天】在数字化时代,网络安全不再是可选项,而是每个网民的必修课。本文旨在深入探讨网络安全的核心要素,包括常见的安全漏洞、先进的加密技术以及不可或缺的安全意识。通过分析这些方面,我们将揭示如何保护个人和组织免受网络攻击的策略,同时提供实用的代码示例,以增强读者的实践能力。文章将引导您思考如何在日益复杂的网络环境中保持警惕,并采取积极措施以确保数据的安全。
12 4
|
1天前
|
SQL 安全 网络安全
网络安全与信息安全:漏洞、加密与安全意识的交织
在数字化时代,网络安全和信息安全的重要性日益凸显。本文深入探讨了网络安全漏洞、加密技术以及安全意识等关键要素,分析了它们之间的相互作用和对维护网络安全的影响。通过实例和代码示例,揭示了网络攻击的常见手段,展示了如何利用加密技术保护数据,以及提升个人和组织的安全意识。本文旨在为读者提供有价值的信息和建议,帮助在复杂的网络环境中更好地保护自己的数字资产。
|
1天前
|
安全 网络协议 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【10月更文挑战第35天】在数字化时代,网络安全和信息安全已成为全球关注的焦点。本文将深入探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供实用的建议和策略,以帮助个人和企业提高网络安全防护能力。通过了解网络安全的基本原理和最佳实践,我们可以更好地保护自己免受网络威胁的侵害。
|
5天前
|
存储 安全 算法
网络安全的屏障与钥匙:漏洞防御、加密技术与安全意识
【10月更文挑战第31天】在数字时代的海洋中,网络安全犹如灯塔指引着信息的安全航行。本文将探讨网络安全的三大支柱:网络漏洞的防御策略、加密技术的应用以及提高个人和组织的安全意识。通过深入浅出的分析,我们将了解如何构建坚固的网络防线,保护数据不受威胁,并提升整个社会对信息安全的认识和重视。
下一篇
无影云桌面