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#的实现代码:

public static class Tea
    {

        public static byte[] Encrypt(byte[] data, byte[] key)
        {

            byte[] dataBytes;
             == )
            {
                dataBytes = data;

            }
            else
            {
                dataBytes = ];
                Array.Copy(data, , dataBytes, , data.Length);
                dataBytes[data.Length] = 0x0;

            }
            ];
            uint[] formattedKey = FormatKey(key);
            ];
            ; i < dataBytes.Length; i += )
            {
                tempData[] = dataBytes[i];
                tempData[] = dataBytes[i + ];
                code(tempData, formattedKey);
                Array.Copy(ConvertUIntToByteArray(tempData[]), , result, i * , );
                Array.Copy(ConvertUIntToByteArray(tempData[]), , result, i *  + , );
            }
            return result;
        }

        public static byte[] Decrypt(byte[] data, byte[] key)
        {
            uint[] formattedKey = FormatKey(key);
            ;
            ];
             * ];
            ; i < data.Length; i += )
            {
                tempData[] = ConvertByteArrayToUInt(data, i);
                tempData[] = ConvertByteArrayToUInt(data, i + );
                decode(tempData, formattedKey);
                dataBytes[x++] = (];
                dataBytes[x++] = (];
            }
            //修剪添加的空字符
            ] == 0x0)
            {
                ];
                Array.Copy(dataBytes, , result, , dataBytes.Length - );
            }
            return dataBytes;

        }

        static uint[] FormatKey(byte[] key)
        {
            )
                throw new ArgumentException("Key must be between 1 and 16 characters in length");
            ];
            )
            {
                Array.Copy(key, , refineKey, , key.Length);
                ; k++)
                {
                    refineKey[k] = 0x20;
                }
            }
            else
            {
                Array.Copy(key, , refineKey, , );
            }
            ];
            ;
            ; i < refineKey.Length; i += )
                formattedKey[j++] = ConvertByteArrayToUInt(refineKey, i);
            return formattedKey;
        }
        #region Tea Algorithm
        static void code(uint[] v, uint[] k)
        {
            ];
            ];
            ;
            uint delta = 0x9e3779b9;
            ;
            )
            {
                sum += delta;
                y += (z << ) + k[] ^ z + sum ^ (z >> ) + k[];
                z += (y << ) + k[] ^ y + sum ^ (y >> ) + k[];
            }
            v[] = y;
            v[] = z;
        }

        static void decode(uint[] v, uint[] k)
        {
            ;
            uint sum;
            ];
            ];
            uint delta = 0x9e3779b9;
            /*
            * 由于进行16轮运算,所以将delta左移4位,减16次后刚好为0.
            */
            sum = delta << ;
            )
            {
                z -= (y << ) + k[] ^ y + sum ^ (y >> ) + k[];
                y -= (z << ) + k[] ^ z + sum ^ (z >> ) + k[];
                sum -= delta;
            }
            v[] = y;
            v[] = z;
        }
        #endregion

        private static byte[] ConvertUIntToByteArray(uint v)
        {
            ];
            result[] = (byte)(v & 0xFF);
            result[] = () & 0xFF);
            result[] = () & 0xFF);
            result[] = () & 0xFF);
            return result;
        }

        private static uint ConvertByteArrayToUInt(byte[] v, int offset)
        {
             > v.Length) ;
            uint output;
            output = (uint)v[offset];
            output |= (] << );
            output |= (] << );
            output |= (] << );
            return output;
        }
    }

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#的实现代码:

using System;

class XXTEA
{
    public static Byte[] Encrypt(Byte[] Data, Byte[] Key)
    {
        )
        {
            return Data;
        }
        return ToByteArray(Encrypt(ToUInt32Array(Data, true), ToUInt32Array(Key, false)), false);
    }
    public static Byte[] Decrypt(Byte[] Data, Byte[] Key)
    {
        )
        {
            return Data;
        }
        return ToByteArray(Decrypt(ToUInt32Array(Data, false), ToUInt32Array(Key, false)), true);
    }

    public static UInt32[] Encrypt(UInt32[] v, UInt32[] k)
    {
        Int32 n = v.Length - ;
        )
        {
            return v;
        }
        )
        {
            UInt32[] Key = ];
            k.CopyTo(Key, );
            k = Key;
        }
        UInt32 z = v[n], y = v[], delta = , e;
        Int32 p, q =  +  / (n + );
        )
        {
            sum = unchecked(sum + delta);
            e = sum >>  & ;
            ; p < n; p++)
            {
                y = v[p + ];
                z =  ^ y << ) + (y >>  ^ z << ) ^ (sum ^ y) + (k[p &  ^ e] ^ z));
            }
            y = v[];
            z =  ^ y << ) + (y >>  ^ z << ) ^ (sum ^ y) + (k[p &  ^ e] ^ z));
        }
        return v;
    }
    public static UInt32[] Decrypt(UInt32[] v, UInt32[] k)
    {
        Int32 n = v.Length - ;
        )
        {
            return v;
        }
        )
        {
            UInt32[] Key = ];
            k.CopyTo(Key, );
            k = Key;
        }
        UInt32 z = v[n], y = v[], delta = 0x9E3779B9, sum, e;
        Int32 p, q =  +  / (n + );
        sum = unchecked((UInt32)(q * delta));
        )
        {
            e = sum >>  & ;
            ; p--)
            {
                z = v[p - ];
                y =  ^ y << ) + (y >>  ^ z << ) ^ (sum ^ y) + (k[p &  ^ e] ^ z));
            }
            z = v[n];
            y = ] -= (z >>  ^ y << ) + (y >>  ^ z << ) ^ (sum ^ y) + (k[p &  ^ e] ^ z));
            sum = unchecked(sum - delta);
        }
        return v;
    }
    private static UInt32[] ToUInt32Array(Byte[] Data, Boolean IncludeLength)
    {
        Int32 n = (((Data.Length & ) == ) ? (Data.Length >> ) : ((Data.Length >> ) + ));
        UInt32[] Result;
        if (IncludeLength)
        {
            Result = ];
            Result[n] = (UInt32)Data.Length;
        }
        else
        {
            Result = new UInt32[n];
        }
        n = Data.Length;
        ; i < n; i++)
        {
            Result[i >> ] |= (UInt32)Data[i] << ((i & ) << );
        }
        return Result;
    }
    private static Byte[] ToByteArray(UInt32[] Data, Boolean IncludeLength)
    {
        Int32 n;
        if (IncludeLength)
        {
            n = (Int32)Data[Data.Length - ];
        }
        else
        {
            n = Data.Length << ;
        }
        Byte[] Result = new Byte[n];
        ; i < n; i++)
        {
            Result[i] = (Byte)(Data[i >> ] >> ((i & ) << ));
        }
        return Result;
    }
}

Tea加密算法和XxTea加密算法的更多相关文章

  1. python实现DES加密算法和3DES加密算法

    pyDes.py ############################################################################# # Documentati ...

  2. 加密算法和MD5等散列算法的区别(转)

    本文转自http://www.cnblogs.com/eternalwt/archive/2013/03/21/2973807.html 感谢作者 1.在软件开发的用户注册功能中常出现MD5加密这个概 ...

  3. RSA加密算法和SSH远程连接服务器

    服务器端与客户端的密钥系统不一样,称为非对称式密钥系统 RSA算法的基础是模运算x mod n,事实上: [(a mod n) + (b mod n)] mod n = (a+b) mod n [(a ...

  4. 利用SHA-1算法和RSA秘钥进行签名验签(带注释)

    背景介绍 1.SHA 安全散列算法SHA (Secure Hash Algorithm)是美国国家标准和技术局发布的国家标准FIPS PUB 180-1,一般称为SHA-1.其对长度不超过264二进制 ...

  5. 介绍XXTEA加密算法及其C实现

    介绍XXTEA加密算法及其C实现 http://en.wikipedia.org/wiki/XXTEA “微型加密算法(TEA)及其相关变种(XTEA,Block TEA,XXTEA)都是分组加密算法 ...

  6. TEA加密

    TEA(Tiny Encryption Algorithm)是一种小型的对称加密解密算法,支持128位密码,与BlowFish一样TEA每次只能加密/解密8字节数据.TEA特点是速度快.效率高,实现也 ...

  7. 数据的加密传输——单片机上实现TEA加密解密算法

    各位大侠在做数据传输时,有没有考虑过把数据加密起来进行传输,若在串口或者无线中把所要传的数据加密起来,岂不是增加了通信的安全性.常用的加密解密算法比如DES.RSA等,受限于单片机的内存和运算速度,实 ...

  8. 单片机上使用TEA加密通信(转)

    源:单片机上使用TEA加密通信 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:MDK4.72 单片机:STM32 说 ...

  9. ANSI-X99MAC算法和PBOC的3DES MAC算法

    仅仅要有标准的DES加密和解密算法.类似ANSI-X99MAC算法和PBOC3DES算法就非常好实现.他们都是用DES算法再经过一层算法实现的.实现原理看图就能看明确.3DES算法实现就更简单了.就是 ...

随机推荐

  1. cf B. Resort

    http://codeforces.com/contest/350/problem/B 从旅馆开始倒着找到一个点它的出度>1的位置为止,比较长度大小,找到一个长度最大的即可. #include ...

  2. Morse Clock

    Morse Clock "di-dah di-di-di-dit di-dah-dah di-dah-dah-dah dah-di-dit dah-di-di-dah", soun ...

  3. linux下能ping ip不能ping域名详解

    今天在开发的同事来说,内网不能通过域名访问自己的服务器!然后做了下面的测试发现这样的问题: [root@itmop ~]# ping www.downcc.com ping: unknown host ...

  4. 低效的SQL引发的cache buffers chains latch

    1.低效的SQL 低效的SQL语句时发生cache buffers chains 锁存器争用的最重要原因.多个进程同时扫描大范围的索引或表时,可能广泛 地发生cache buffers chains ...

  5. 2013第46周四xml作为WS两端中间测试文件

    今天又到了11点多才开始写随笔记录,有点惭愧,加班回来到现在已经近2小时了,而我此刻才进入正题,之前的时间都跟MM聊天了,或许是单身久了,居然在个人情感方面感觉自己很out了,不想这些了,重点是回顾下 ...

  6. OpenMeetings(3)----启动顺序解析

    OpenMeetings系统较大,代码量也不小,如果对前端的OpenLaszlo开发不熟悉的话,刚研究代码时,确实有种丈二和尚摸不着头脑的感觉.一番研究之后,终于初步理清了系统的初步动作流程,具体执行 ...

  7. memcached学习——memcached的内存分配机制Slab Allocation、内存使用机制LRU、常用监控记录(四)

    内存分配机制Slab Allocation 本文参考博客:https://my.oschina.net/bieber/blog/505458 Memcached的内存分配是以slabs为单位的,会根据 ...

  8. 【转】linux 关机命令总结

    linux下常用的关机命令有:shutdown.halt.poweroff.init:重启命令有:reboot.下面本文就主要介绍一些常用的关机命令以及各种关机命令之间的区别和具体用法. 首先来看一下 ...

  9. ubuntu 14.04 下试用Sublime Text 3

    很多源代码都没有IDE支持的,尤其是开源的源代码.从github上下载的,很多也不用IDE.包括我自己公司的代码,基本都是脚本,也不用IDE.通常情况下,都是用notepad++.UE之类的文本编辑器 ...

  10. python学习之路-5 基础进阶篇

    本篇涉及内容 双层装饰器字符串格式化 双层装饰器 装饰器基础请点我 有时候一个功能需要有2次认证的时候就需要用到双层装饰器了,下面我们来通过一个案例详细介绍一下双层装饰器: 执行顺序:自上而下 解释顺 ...