TEA

它是一种分组密码算法,其明文密文块为64比特,密钥长度为128比特。TEA算法利用不断增加的Delta(黄金分割率)值作为变化,使得每轮的加密是不同,该加密算法的迭代次数可以改变,建议的迭代次数为32轮。
Tea算法的特征是存在0x9e3779b9.
加密:

#include<stdio.h>
void encode(unsigned int* v,unsigned int *k)
{
    unsigned int l=v[0],r=v[1];
    unsigned int k0=k[0],k1=k[1],k2=k[2],k3=k[3];
    unsigned int delta=0x9e3779b9;
    int i;
    unsigned int sum=0;
    for(i=0;i<32;i++)          //核心加密算法,建议32轮,最低16轮
    {
        sum+=delta;
        l+=((r<<4)+k0)^(r+sum)^((r>>5)+k1);     //r<<4/r*16
        r+=((l<<4)+k2)^(l+sum)^((l>>5)+k3);
    }
    v[0]=l;
    v[1]=r;
}
int main()
{
    unsigned int a[2]={1,2}; //明文,必须是8字节的倍数,不够需要程序补全,参考base64方法
    unsigned int k[4]={2,2,3,4};//密钥随便
    encode(a,k);
    printf("%d %d",a[0],a[1]);
}

解密:

uint32_t v0=v[0], v1=v[1], sum=0xC6EF3720, i;  //由加密轮数而算出
  uint32_t delta=0x9e3779b9;                     
  uint32_t k0=k[0], k1=k[1], k2=k[2], k3=k[3]; 
  for (i=0; i<32; i++) {                                    //核心解密算法
      v1 -= ((v0<<4) + k2) ^ (v0 + sum) ^ ((v0>>5) + k3);
      v0 -= ((v1<<4) + k0) ^ (v1 + sum) ^ ((v1>>5) + k1);
      sum -= delta;
  }                                           
  v[0]=v0; v[1]=v1;

TEA算法逆向

  1. tea算法的特征就是DELTA值和十六个字节的密钥(也就是128位)。
  2. 在逆向程序的时候,可以利用ida的插件findcypto识别tea算法
  3. x-=0x61c88647和x+=0x9e3779b9,这两个值是等价的,可能会在反汇编中看到

    TEA算法的变化技巧

    前面有提到关于”但δ的精确值似乎并不重要”,所以δ的值不一定需要0x9E3779B9,所以这里的话在加密解密的时候可以改变这个δ的值,改了之后就会导致部分识别加密的工具失效来达到算法魔改的目的。
    测试代码,改变其中的δ的值
    //加密函数
    void encrypt(uint32_t* v, uint32_t* k) {
       uint32_t v0 = v[0], v1 = v[1], sum = 0, i;           /* set up */
       uint32_t delta = 0x12345678;                     /* a key schedule 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 = 0x468acf00, i;  /* set up */
       uint32_t delta = 0x12345678;                     /* a key schedule 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;
    }

    XTEA

    XTEA是TEA的升级版,增加了更多的密钥表,移位和异或操作等等,也被称为”tean”
    加密:
    #include<stdio.h>
    #include<stdint.h>
     
    void encipher(unsigned int num_rounds, uint32_t v[2], uint32_t const key[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+key[sum&3]);
          sum+=delta;
          v1+=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);
       }
       v[0]=v0;v[1]=v1;
    }
     
    void decipher(unsigned int num_rounds,uint32_t v[2],uint32_t const key[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-=(((v0<<4)^(v0>>5))+v0)^(sum+key[(sum>>11)&3]);
       sum-=delta;
       v0-=(((v1<<4)^(v1>>5))+v1)^(sum+key[sum&3]);
       } 
       v[0]=v0;v[1]=v1;
    }
     
    int main(){
       uint32_t v[2]={1,2};
       uint32_t const k[4]={2,2,3,4};
       unsigned int r=32;				//这里是加密轮数,自己设置 
       printf("加密前原始数据:%u %u\n",v[0],v[1]);
       encipher(r,v,k);
       printf("加密后原始数据:%u %u\n",v[0],v[1]);
       decipher(r,v,k);
       printf("解密后原始数据:%u %u\n",v[0],v[1]);
       return 0;
    }
    解密:
    void decrypt(unsigned int* v, unsigned int* key) {
      unsigned int l = v[0], r = v[1], sum = 0, delta = 0x9e3779b9;
      sum = delta * 32;
      for (size_t i = 0; i < 32; i++) {
        r -= (((l << 4) ^ (l >> 5)) + l) ^ (sum + key[(sum >> 11) & 3]);
        sum -= delta;
        l -= (((r << 4) ^ (r >> 5)) + r) ^ (sum + key[sum & 3]);
      }
      v[0] = l;
      v[1] = r;
    }
    下面是TEA和XTEA两种算法之间的主要区别:
  4. 密钥长度不同:TEA算法采用128位密钥,而XTEA算法采用更长的256位密钥。
  5. 加密轮数不同:TEA算法采用32轮迭代加密/解密,而XTEA算法采用64轮迭代加密/解密。这使得XTEA算法有更好的安全性,但也使得它相对于TEA算法来说更加耗时。
  6. 算法细节不同:XTEA算法在TEA算法的基础上进行了改进,主要针对TEA算法中的一些安全弱点。具体来说,XTEA算法中的迭代加密/解密中加入了一个变量delta的变化,以增强算法的安全性。此外,XTEA算法中的轮加密过程也做了一些微调,例如将密钥扩展的方式做了改进等。

    XXTEA

    又称Corrected Block TEA
    特点:原字符串长度可以不是4的倍数了
    #include <stdbool.h>
    #include <stdio.h>
    #define MX \
      ((z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z))
    bool btea(unsigned int* v, int n, unsigned int* k) {
      unsigned int z = v[n - 1], y = v[0], sum = 0, e, DELTA = 0x9e3779b9;
      unsigned int p, q;
      if (n > 1) { /* Coding Part */
        q = 6 + 52 / n;
        while (q-- > 0) {
          sum += DELTA;
          e = (sum >> 2) & 3;
          for (p = 0; p < n - 1; p++)
            y = v[p + 1], z = v[p] += MX;
          y = v[0];
          z = v[n - 1] += MX;
        }
        return 0;
      } else if (n < -1) { /* Decoding Part */
        n = -n;
        q = 6 + 52 / n;
        sum = q * DELTA;
        while (sum != 0) {
          e = (sum >> 2) & 3;
          for (p = n - 1; p > 0; p--)
            z = v[p - 1], y = v[p] -= MX;
          z = v[n - 1];
          y = v[0] -= MX;
          sum -= DELTA;
        }
        return 0;
      }
      return 1;
    }
     
    int main(int argc, char const* argv[]) {
      // test
      unsigned int v[2] = {1, 2}, key[4] = {1, 2, 3, 4};
      printf("%u,%u\n", v[0], v[1]);
      btea(v, 2, key);
      printf("%u,%u\n", v[0], v[1]);
      btea(v, -2, key);
      printf("%u,%u\n", v[0], v[1]);
      return 0;
    }
    在线解密网址:http://www.atoolbox.net/Tool.php?Id=861