首页
社区
课程
招聘
[旧帖] [分享]数据加密算法总结 0.00雪花
发表于: 2009-10-9 13:06 3170

[旧帖] [分享]数据加密算法总结 0.00雪花

2009-10-9 13:06
3170

数据加密算法
数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为“密文”,使其只能在输入相应的密钥之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人窃取、阅读的目的。该过程的逆过程为解密,即将该编码信息转化为其原来数据的过程。

加密技术通常分为:“对称式”, “非对称式”, “数字摘要算法”。

1. 对称式加密就是加密和解密使用同一个密钥,通常称之为“Session Key ”这种加密技术目前被广泛采用,如美国政府所采用的DES加密标准就是一种典型的“对称式”加密法,它的Session Key长度为56Bits。

对称式加密算法又分为流加密与块加密。

流加密算法, 如 RC4,  加密的数据是可变的。
块加密算法, 如DES, IDEA, AES 等, 加密的数据块是固定的。

2. 非对称式加密就是加密和解密所使用的不是同一个密钥,通常有两个密钥,称为“公钥”和“私钥”,它们两个必需配对使用,否则不能打开加密文件。这里的“公钥”是指可以对外公布的,“私钥”则不能,只能由持有人一个人知道。它的优越性就在这里,因为对称式的加密方法如果是在网络上传输加密文件就很难把密钥告诉对方,不管用什么方法都有可能被别窃听到。而非对称式的加密方法有两个密钥,且其中的“公钥”是可以公开的,也就不怕别人知道,收件人解密时只要用自己的私钥即可以,这样就很好地避免了密钥的传输安全性问题。如 RSA 算法

3. 数字摘要(Digital Digest)。该加密方法也是由Ron Rivest设计的,也被称为安全Hash编码法SHA(Secure Hash Algorithm)或MD5(MD Standards for Message Digest)。该编码法采用单向Hash函数[1]将需加密的明文“摘要”成一串128bit(位)的密文,这一串密文也称为数字指纹(Finger Print),它具有固定的长度。而且不同的明文摘要成密文时,其指纹结果也是不同的,而相同明文的摘要必定相同。这样,这串摘要便可以成为验证明文是否是“真身”的“指纹”了。SHA其实就是RC方法的一种实现。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 7
支持
分享
最新回复 (15)
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
楼上能给个AES 算法的C实现吗?
谢谢
2009-10-9 13:25
0
雪    币: 69
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
可以啊! 不知如何给你?
2009-10-9 16:01
0
雪    币: 49
活跃值: (19)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
没代码的话
这个不能算总结 只能算简介。
2009-10-9 16:08
0
雪    币: 69
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
代码太多了,贴出来很乱的!
我实现有DES, TDES, AES, IDEA, RSA, MD5, SHA1 全部由c++ porting 为 C
2009-10-9 17:58
0
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
挑有代表性的
2009-10-9 18:58
0
雪    币: 261
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
打包吧!欢迎
2009-10-9 20:45
0
雪    币: 69
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
8
响应大家要求,贴有代表性代码和大家研究学习!

des 算法 (所占用的空间是比较小的,全部下来,约两K)
/****************************************************/
code BYTE pc_1[56] =       
        { 56,  48,  40,  32,  24,  16,   8,
           0,  57,  49,  41,  33,  25,  17,
              9,   1,  58,  50,  42,  34,  26,     
             18,  10,   2,  59,  51,  43,  35,
              62,  54,  46,  38,  30,  22,  14,   
           6,  61,  53,  45,  37,  29,  21,
            13,   5,  60,  52,  44,  36,  28,
                20,  12,   4,  27,  19,  11,   3 };

/* Key use(56bit ->- 48bit)                */
code BYTE pc_2[48] =
                { 13,  16,  10,  23,   0,   4,   2,  27,
                  14,   5,  20,   9,  22,  18,  11,   3,
                  25,   7,  15,   6,  26,  19,  12,   1,
                           40,  51,  30,  36,  46,  54,  29,  39,
                  50,  44,  32,  47,  43,  48,  38,  55,
                  33,  52,  45,  41,  49,  35,  28,  31  };

/* Key use(move bit)  */
code BYTE        ccmovebit1[16] =
                { 1,1,2,2,2,2,2,2,1,2,2,2,2,2,2,1};

/************************************************/
/* Data use(64bit ->- 64bit)                          0--63*/
code BYTE  ip[64] =
                {    57,  49,  41,  33,  25,  17,   9,   1,
                     59,  51,  43,  35,  27,  19,  11,   3,
                     61,  53,  45,  37,  29,  21,  13,   5,
                     63,  55,  47,  39,  31,  23,  15,   7,
                     56,  48,  40,  32,  24,  16,   8,   0,
                     58,  50,  42,  34,  26,  18,  10,   2,
                     60,  52,  44,  36,  28,  20,  12,   4,
                     62,  54,  46,  38,  30,  22,  14,   6  };

/* Data use(R32 32bit ->- 48bit)  */
code BYTE e[48] =
        { 31,   0,   1,   2,   3,   4,   3,   4,
                   5,   6,   7,   8,   7,   8,   9,  10,
                  11,  12,  11,  12,  13,  14,  15,  16,
                  15,  16,  17,  18,  19,  20,  19,  20,
                  21,  22,  23,  24,  23,  24,  25,  26,
                  27,  28,  27,  28,  29,  30,  31,   0   };

/* Data use(R32-R32  32bit ->- 32bit)        code 0-31*/
code BYTE p[32] =
                { 15,   6,  19,  20,  28,  11,  27,  16,
               0,  14,  22,  25,   4,  17,  30,   9,
                   1,   7,  23,  13,  31,  26,   2,   8,
                    18,  12,  29,   5,  21,  10,   3,  24  };

       
/* Data use(32L+32R  ->-  64bit)  */
code  BYTE ip_1[64] =
                { 39,        7,        47,         15,  55,  23,  63,  31,
                  38,        6,        46,         14,  54,  22,  62,  30,
                  37,        5,        45,         13,  53,  21,  61,         29,
                  36,        4,        44,         12,  52,  20,  60,         28,
                  35,        3,        43,         11,  51,  19,  59,         27,
                  34,        2,        42,         10,  50,  18,  58,         26,
                  33,        1,        41,          9,  49,  17,  57,         25,
                  32,        0,        40,          8,  48,  16,        56,         24         };

/**********************************************/
#if 0
code BYTE s[8][32] ={
{  /* s0*/
0xe0,        0x4f,        0xd7,        0x14, 0x2e,        0xf2,        0xbd,        0x81,
0x3a,        0xa6,        0x6c,        0xcb, 0x59,        0x95,        0x03,        0x78,
0x4f,        0x1c,        0xe8,        0x82, 0xd4,        0x69,        0x21,        0xb7,
0xf5,        0xcb,        0x93,        0x7e, 0x3a,        0xa0,        0x56,        0x0d         },

{         /* s1*/
0xf3,        0x1d,        0x84,        0xe7, 0x6f,        0xb2,        0x38,        0x4e,
0x9c,        0x70,        0x21,        0xda, 0xc6,        0x09,        0x5b,        0xa5,
0x0d,        0xe8,        0x7a,        0xb1, 0xa3,        0x4f,        0xd4,        0x12,       
0x5b,        0x86,        0xc7,        0x6c, 0x90,        0x35,        0x2e,        0xf9  },

{        /*  s2*/
0xad,        0x07,        0x90,        0xe9, 0x63,        0x34,        0xf6,        0x5a,
0x12,        0xd8,        0xc5,        0x7e, 0xbc,        0x4b,        0x2f,        0x81,
0xd1,        0x6a,        0x4d,        0x90, 0x86,        0xf9,        0x38,        0x07,
0xb4,        0x1f,        0x2e,        0xc3, 0x5b,        0xa5,        0xe2,        0x7c         },

{        /* s3*/
0x7d,        0xd8,        0xeb,        0x35, 0x06,        0x6f,        0x90,        0xa3,
0x14,        0x27,        0x82,        0x5c, 0xb1,        0xca,        0x4e,        0xf9,
0xa3,        0x6f,        0x90,        0x06, 0xca,        0xb1,        0x7d,        0xd8,
0xf9,        0x14,        0x35,        0xeb, 0x5c,        0x27,        0x82,        0x4e,  },

{          /* s4*/
0x2e,        0xcb,   0x42,        0x1c,  0x74,        0xa7,        0xbd,        0x61,
0x85,        0x50,        0x3f,        0xfa,  0xd3,        0x09,   0xe8,        0x96,
0x4b,        0x28,        0x1c,        0xb7,  0xa1,        0xde,        0x72,        0x8d,
0xf6,        0x9f,        0xc0,        0x59,  0x6a,        0x34,        0x05,        0xe3   },

{          /* s5*/
0xca,        0x1f,        0xa4,        0xf2, 0x97,        0x2c,        0x69,        0x85,
0x06,        0xd1,        0x3d,        0x4e, 0xe0,        0x7b,        0x53,        0xb8,
0x94,        0xe3,        0xf2,        0x5c, 0x29,        0x85,        0xcf,        0x3a,
0x7b,        0x0e,        0x41,        0xa7, 0x16,        0xd0,        0xb8,        0x6d   },

{         /* s6*/
0x4d,        0xb0,        0x2b,        0xe7,  0xf4,        0x09,        0x81,        0xda,
0x3e,        0xc3,        0x95,        0x7c,  0x52,        0xaf,        0x68,        0x16,
0x16,        0x4b,        0xbd,        0xd8,  0xc1,        0x34,        0x7a,        0xe7,
0xa9,        0xf5,        0x60,        0x8f,  0x0e,        0x52,        0x93,   0x2c          },

{      /* s7                                              */
0xd1,        0x2f,        0x8d,        0x48,  0x6a,        0xf3,        0xb7,        0x14,
0xac,        0x95,        0x36,        0xeb,  0x50,        0x0e,        0xc9,        0x72,
0x72,        0xb1,        0x4e,        0x17,  0x94,        0xca,        0xe8,        0x2d,
0x0f,        0x6c,        0xa9,        0xd0,  0xf3,        0x35,        0x56,        0x8b          }

};
#else
BYTE sbox[8][32] ={
{0xe4,        0xd1,        0x2f,        0xb8,   0x3a,        0x6c,        0x59,        0x07,
0x0f,        0x74,        0xe2,        0xd1,   0xa6,        0xcb,        0x95,        0x38,
0x41,        0xe8,        0xd6,        0x2b,   0xfc,        0x97,        0x3a,        0x50,
0xfc,        0x82,        0x49,        0x17,   0x5b,        0x3e,        0xa0,        0x6d },
{0xF1,  0x8E,   0x6B,   0x34,   0x97,   0x2D,   0xC0,   0x5A,
0x3D,        0x47,        0xF2,        0x8E,        0xC0,        0x1A,        0x69,        0xB5,       
0x0E,        0x7B,        0xA4,        0xD1,        0x58,        0xC6,        0x93,        0x2F,       
0xD8,        0xA1,        0x3F,        0x42,        0xB6,        0x7C,        0x5,        0xE9},       
{0xA0,        0x9E,        0x63,        0xF5,        0x1D,        0xC7,        0xB4,        0x28,       
0xD7,        0x09,        0x34,        0x6A,        0x28,        0x5E,        0xCB,        0xF1,       
0xD6,        0x49,        0x8F,        0x30,        0xB1,        0x2C,        0x5A,        0xE7,       
0x1A,        0xD0,        0x69,        0x87,        0x4F,        0xE3,        0xB5,        0x2C},       
{0x7D,        0xE3,        0x6,        0x9A,        0x12,        0x85,        0xBC,        0x4F,       
0xD8,        0xB5,        0x6F,        0x3,        0x47,        0x2C,        0x1A,        0xE9,       
0xA6,        0x90,        0xCB,        0x7D,        0xF1,        0x3E,        0x52,        0x84,       
0x3F,        0x6,        0xA1,        0xD8,        0x94,        0x5B,        0xC7,        0x2E},       
{0x2C,        0x41,        0x7A,        0xB6,        0x85,        0x3F,        0xD0,        0xE9,       
0xEB,        0x2C,        0x47,        0xD1,        0x50,        0xFA,        0x39,        0x86,       
0x42,        0x1B,        0xAD,        0x78,        0xF9,        0xC5,        0x63,        0xE,       
0xB8,        0xC7,        0x1E,        0x2D,        0x6F,        0x9,        0xA4,        0x53},       
{0xC1,        0xAF,        0x92,        0x68,        0xD,        0x34,        0xE7,        0x5B,         
0xAF,        0x42,        0x7C,        0x95,        0x61,        0xDE,        0xB,        0x38,       
0x9E,        0xF5,        0x28,        0xC3,        0x70,        0x4A,        0x1D,        0xB6,       
0x43,        0x2C,        0x95,        0xFA,        0xBE,        0x17,        0x60,        0x8D},       
{0x4B,        0x2E,        0xF0,        0x8D,        0x3C,        0x97,        0x5A,        0x61,       
0xD0,        0xB7,        0x49,        0x1A,        0xE3,        0x5C,        0x2F,        0x86,       
0x14,        0xBD,        0xC3,        0x7E,        0xAF,        0x68,        0x5,        0x92,       
0x6B,        0xD8,        0x14,        0xA7,        0x95,        0xF,        0xE2,        0x3C},       
{0xD2,        0x84,        0x6F,        0xB1,        0xA9,        0x3E,        0x50,        0xC7,         
0x1F,        0xD8,        0xA3,        0x74,        0xC5,        0x6B,        0xE,        0x92,       
0x7B,        0x41,        0x9C,        0xE2,        0x6,        0xAD,        0xF3,        0x58,       
0x21,        0xE7,        0x4A,        0x8D,        0xFC,        0x90,        0x35,        0x6B},       
};

#endif

//================= Global Functions ================================
BYTE key_n[96];

//----------------------  ExpandTo64  -----------------------------------
/*!
*\brief PURPOSE:  Get 64 byte data expanded from 8-byte array.
*
*\par Description
         Change 8-byte array into 64-byte array, each bit stored as byte.
         
*\param[in]  Array8     -  8-byte array
*\param[in]  bits       -  count of bits
*\param[out] Array64    -  64-byte array
*\return
         no
*\note

*\see  
       
*\bug
        None
*\test
        No test
*\todo
        NO  
*/
/*-------------------------------------------------------------*/
void ExpandTo64(BYTE *Array8, BYTE *Array64, BYTE bits)
{
   BYTE i;
   for(i=0; i<bits; i++)
           Array64[i] = (Array8[i>>3] >> (7-(i& 0x7))) & 1;

}
/*----------------------   ContractTo8  -----------------------------------*/
/*!
*\brief PURPOSE:  Get 8 byte data compress from 64-byte array.
*
*\par Description
         Change 64-byte array into 8-byte array, each 8 -byte store as  1-byte .

  *\param[in] Array64     -  64-byte array        
  *\param[in]  bits        -  count of bits
  *\param[out]  Array8     -  8-byte array

*\return
         
*\note

*\see  
       
*\bug
        None
*\test
        No test
*\todo
        NO  
*/
/*-------------------------------------------------------------*/
void   ContractTo8(BYTE *Array64, BYTE *Array8, BYTE bits)
{
   BYTE i,j;
   for(i = 0; i < bits/8; i++)
   {
           Array8[i]=0;
           for (j=0;j<8;j++)
                if (Array64[i*8 +j])
                        Array8[i]|=(0x01<<(7-j));
   }

}

/*----------------------  GenSubKey  -----------------------------------*/
/*!
*\brief PURPOSE:  Process 16 sub key from 8-byte key.
*
*\par Description
          1. Calculate the key schedule, reducing 8-byte key to 56 bits
          2. Split the permuted key into two halves.
          3. Calculate the 16 subkeys, Get 16-group 48-bit sub key from 8-byte key.
         
*\param[in]  oldkey      -  8-byte key array
*\param[out]  newkey   - 16 group sub key array

*\return
         
*\note

*\see  
       
*\bug
        None
*\test
        No test
*\todo
        NO  
*/
/*-------------------------------------------------------------*/
void  GenSubKey(const BYTE oldkey[8], BYTE newkey[96])
{
     BYTE i, k, rol = 0;
        BYTE oldkey_c[28];
        BYTE oldkey_d[28];
     BYTE newkey_byte[64];
     BYTE *p;
     signed char tmp;

     ExpandTo64(oldkey, newkey_byte, 64);

     for(i = 0; i < 28; i++)
     {
             oldkey_c[i] = newkey_byte[pc_1[i]];
             oldkey_d[i] = newkey_byte[pc_1[i+28]];
     }

     for(i = 0; i < 16; i++)
     {
               rol += ccmovebit1[i];
           for(k = 0; k < 48; k++)
           {
                              tmp = pc_2[k];
                             p   = (tmp<28) ? (oldkey_c+rol) : (tmp-=28, oldkey_d+rol);
                                 if (tmp+rol>=28)
                                       tmp-=28;
                               newkey_byte[k] =*(p+tmp);
                   }
           ContractTo8(newkey_byte, newkey+i*6, 48);
     }

}

/*----------------------  sReplace  -----------------------------------*/
/*!
*\brief PURPOSE:  Change 48-bits into 32-bits and replace.
*
*\par Description
          Substitute the values in the S-boxes for 48-bits.
         
*\param[in,out]  s_byte      -   48-bits data array for input and 32-bits data array for output   

*\return
         
*\note

*\see  
                                                         
*\bug
        None
*\test
        No test
*\todo
        NO  
*/
/*-------------------------------------------------------------*/
void sReplace(BYTE s_bit[48])
{
    BYTE i,j,tmp1,tmp2,tmp;
    BYTE s_bit1[32] = 0x0;
    BYTE s_count;
#if 0   
    for(i= 0; i<8; i++){
         s_count = 0;
         for(j=(i*6); j<(i+1)*6; j++)
                 s_count |= (s_bit[j] << (5-j%6));
         tmp= s[i][s_count/2] ;
         tmp =(s_count & 0x01)? (tmp&0x0F): ((tmp>>4)&0x0F);
         for(j=0; j<4; j++)
                 s_bit1[i*4+j] = (tmp >> (3 - j)) & 0x01;
   }
#else
          for(i=0; i<8; i++)
        {   
             tmp1 = 0;
                 tmp2 = 0;
             tmp1 = (s_bit[i*6]?0x02:0x0) + (s_bit[i*6+5]?0x01:0x0);
                 tmp2 = (s_bit[i*6+1]?0x08:0x0);
                 tmp2 |= (s_bit[i*6+2]?0x04:0x0);
                  tmp2 |= (s_bit[i*6+3]?0x02:0x0);
                  tmp2 |= (s_bit[i*6+4]?0x01:0x0);
                 tmp = (tmp1<<3)+tmp2/2;
                 s_count = (tmp2&0x01)? (sbox[i][tmp]&0x0F): ((sbox[i][tmp]>>4)&0x0F);
             for(j=0; j<4; j++)
                 s_bit1[i*4+j] = (s_count >> (3 - j)) & 0x01;
        }

#endif
   
   for(i = 0; i < 32; i++)               
        s_bit[i]=s_bit1[p[i]];

}

/*----------------------  endeDes  -----------------------------------*/
/*!
*\brief PURPOSE:  Process of Des arithmetic.
*
*\par Description
          1. Get 16 subkey form inkey.
          2. Replace indata and Divide into Letf 32-bits and Right 32-bits  
          3.         16 iterative operation, use subkey.
          4. Left 32-bits and Right 32-bits compose  64 bits, and Replace.
          5. Change 64-bits into 8-byte as output.
         
*\param[in]  indata      -   data which input for encrypt or decrypt
*\param[in]  len          -   length of data
*\param[in]  inkey      -    key
*\param[in]  enflag       -   flag of encrypt, 0--decrypt,  1--encrypt
*\param[out]  outdata  -    output data  which get cryptograph or proclaimed in writing  

*\return
            
*\note

*\see  
       
*\bug
        None
*\test
        No test
*\todo
        NO  
*/
/*-------------------------------------------------------------*/
BOOL  endeDesC(BYTE *indata, int len, BYTE inkey[8], BYTE *outdata, BOOL enflag)
{

BYTE i,j,k,r;
BYTE m_bit[64];
BYTE l_bit[32];
BYTE r_bit[64];
BYTE r_bit0[32];
BYTE r_byte[6] ;

   if((len & 0x7) != 0x0)         // not 8*x, to exit  
       return false;
   
   GenSubKey(inkey, key_n);
     
   for(k=0; k<len; k+=8){
           
                   ExpandTo64(indata+k, m_bit,64);

                   for(i = 0; i < 32; i++)
                   {
                        l_bit[i] = m_bit[ip[i]];     
                        r_bit[i] = m_bit[ip[i+32]];
                r_bit0[i] = r_bit[i];          
                   }
                   for(i = 1; i <= 16; i++)
                   {
                        for(j = 0; j < 48; j++)
                                m_bit[j] = r_bit[e[j]];
                         ContractTo8(m_bit, r_byte,48);       
                        for(j = 0; j < 6; j++)
                      {
                            r = (enflag) ? (i-1) : (16-i);   // jia-mi  jie-mi
                           r_byte[j] ^= key_n[r*6+j];
                        }

                        ExpandTo64(r_byte, r_bit,48);

                        sReplace(r_bit);

                        for(j=0; j<32; j++)
                        {
                                       r_bit[j] ^= l_bit[j];
                                 l_bit[j]  = r_bit0[j];
                                 r_bit0[j] = r_bit[j];
             }

              }

        for(i = 0; i<64; i++)
                    m_bit[i] = (ip_1[i] < 32) ?r_bit[ip_1[i]] : l_bit[ip_1[i] -32];

              ContractTo8(m_bit, outdata+k, 64);
    }

    return true;
}

/**************************************************************/
2009-10-10 09:55
0
雪    币: 69
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
AES 算法
/************************************************/
#include "aes/aes.h"
#include <string.h>
/*
Check arithmetic
Key       :000102030405060708090a0b0c0d0e0f(128bit)  
Plain data:00112233445566778899AABBCCDDEEFF
En-Result :69C4E0D86A7B0430D8CDB78070B4C55A
Decodedata:69C4E0D86A7B0430D8CDB78070B4C55A
De-Result :00112233445566778899AABBCCDDEEFF
*/

#if KEY_COUNT > 0

#define BPOLY 0x1b /* !< Lower 8 bits of (x^8+x^4+x^3+x+1), ie. (x^4+x^3+x+1). */
#define BLOCKSIZE 16 /* !< Block size in number of UINT8s. */

#if KEY_COUNT == 1
        #define KEYBITS 128  /* !< Use AES128. */
#elif KEY_COUNT == 2
        #define KEYBITS 192  /* !< Use AES196.  */
#elif KEY_COUNT == 3
        #define KEYBITS 256  /* !< Use AES256.  */
#else
        #error Use 1, 2 or 3 keys!
#endif

#if KEYBITS == 128
        #define ROUNDS 10    /* !< Number of rounds. */
        #define KEYLENGTH 16 /* !< Key length in number of UINT8s. */
#elif KEYBITS == 192
        #define ROUNDS 12    /* !< Number of rounds. */
        #define KEYLENGTH 24 /* !< Key length in number of UINT8s. */
#elif KEYBITS == 256
        #define ROUNDS 14    /* !< Number of rounds. */
        #define KEYLENGTH 32 /* !< Key length in number of UINT8s. */
#else
        #error Key must be 128, 192 or 256 bits!
#endif

#define EXPANDED_KEY_SIZE (BLOCKSIZE*(ROUNDS+1))

UINT8 block1[256];
UINT8 block2[256];
UINT8 tempbuf[256];

const UINT8 kTable[16] = {0x0};
/* =
{         0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
         0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
};        */

UINT8 *powTbl      = NULL; /* !< Final location of exponentiation lookup table.*/
UINT8 *logTbl      = NULL; /* !< Final location of logarithm lookup table.           */
UINT8 *sBox        = NULL; /* !< Final location of s-box.                                           */
UINT8 *sBoxInv     = NULL; /* !< Final location of inverse s-box.                           */
UINT8 *expandedKey = NULL; /* !< Final location of expanded key.                           */

void CalcPowLog(UINT8 * powTbl, UINT8 * logTbl )
{
    UINT8 i = 0;
    UINT8 t = 1;

    do
        {  /* Use 0x03 as root for exponentiation and logarithms. */
       powTbl[i] = t;
       logTbl[t] = i;
       i++;            /* Muliply t by 3 in GF(2^8). */
       t ^= (t << 1) ^ (t & 0x80 ? BPOLY : 0);
    } while( t != 1 ); /* Cyclic properties ensure that i < 255. */
    powTbl[255] = powTbl[0]; /* 255 = '-0', 254 = -1, etc. */
}

void CalcSBox( UINT8 * sBox )
{
    UINT8 i, rot;
    UINT8 temp;
        UINT8 result;
        i = 0;
        do
        {   /* Inverse in GF(2^8).  */
        if( i > 0 )
                {   temp = powTbl[ 255 - logTbl[i] ];   }
                else
                {   temp = 0;          }
        /* Affine transformation in GF(2). */
        result = temp ^ 0x63; /* Start with adding a vector in GF(2). */
        for( rot = 0; rot < 4; rot++ )
                {   // Rotate left.
                        temp = (temp<<1) | (temp>>7);
                    // Add rotated UINT8 in GF(2).
                        result ^= temp;
                }
                // Put result in table.
        sBox[i] = result;
        }while( ++i != 0 );
}       

void CalcSBoxInv( UINT8 * sBox, UINT8 * sBoxInv )
{
        UINT8 i = 0;
        UINT8 j = 0;
        // Iterate through all elements in sBoxInv using  i.
        do
        {        // Search through sBox using j.
                do
                {        // Check if current j is the inverse of current i.
                        if( sBox[ j ] == i )
                        {   // If so, set sBoxInc and indicate search finished.
                                sBoxInv[ i ] = j;
                                j = 255;
                        }
                }while( ++j != 0 );
        }while( ++i != 0 );
}

void CycleLeft( UINT8 *row )
{
        // Cycle 4 UINT8s in an array left once.
        UINT8 temp = row[0];
        row[0] = row[1];
        row[1] = row[2];
        row[2] = row[3];
        row[3] = temp;
}

void CalcCols(UINT8 *col)
{
  UINT8 i;

  for(i = 4; i > 0; i--)
  {
    *col = (*col << 1) ^ (*col & 0x80 ? BPOLY : 0);
    col++;
  }
}

void InvMixColumn( UINT8 * column )
{
  unsigned char r[4];
  r[0] = column[1] ^ column[2] ^ column[3];
  r[1] = column[0] ^ column[2] ^ column[3];
  r[2] = column[0] ^ column[1] ^ column[3];
  r[3] = column[0] ^ column[1] ^ column[2];

  CalcCols(column);

  r[0] ^= column[0] ^ column[1];
  r[1] ^= column[1] ^ column[2];
  r[2] ^= column[2] ^ column[3];
  r[3] ^= column[0] ^ column[3];

  CalcCols(column);

  r[0] ^= column[0] ^ column[2];
  r[1] ^= column[1] ^ column[3];
  r[2] ^= column[0] ^ column[2];
  r[3] ^= column[1] ^ column[3];

  CalcCols(column);

  column[0] ^= column[1] ^ column[2] ^ column[3];
  r[0] ^= column[0];
  r[1] ^= column[0];
  r[2] ^= column[0];
  r[3] ^= column[0];
  
  column[0] = r[0];
  column[1] = r[1];
  column[2] = r[2];
  column[3] = r[3];
}

void SubBytes( UINT8 * bytes, UINT8 count )
{
  do {
    *bytes = sBox[ *bytes ]; // Substitute every byte in state.
    bytes++;
  } while( --count );
}

void InvSubBytesAndXOR( UINT8 * bytes, UINT8 * key, UINT8 count )
{
  do {
    // *bytes = sBoxInv[ *bytes ] ^ *key; // Inverse substitute every byte in state and add key.
    *bytes = block2[ *bytes ] ^ *key; // Use block2 directly. Increases speed.
    bytes++;
    key++;
  } while( --count );
}

void InvShiftRows( UINT8 * state )
{
        UINT8 temp;

        // Note: State is arranged column by column.
        // Cycle second row right one time.
        temp = state[ 1 + 3*4 ];
        state[ 1 + 3*4 ] = state[ 1 + 2*4 ];
        state[ 1 + 2*4 ] = state[ 1 + 1*4 ];
        state[ 1 + 1*4 ] = state[ 1 + 0*4 ];
        state[ 1 + 0*4 ] = temp;

        // Cycle third row right two times.
        temp = state[ 2 + 0*4 ];
        state[ 2 + 0*4 ] = state[ 2 + 2*4 ];
        state[ 2 + 2*4 ] = temp;
        temp = state[ 2 + 1*4 ];
        state[ 2 + 1*4 ] = state[ 2 + 3*4 ];
        state[ 2 + 3*4 ] = temp;

        // Cycle fourth row right three times, ie. left once.
        temp = state[ 3 + 0*4 ];
        state[ 3 + 0*4 ] = state[ 3 + 1*4 ];
        state[ 3 + 1*4 ] = state[ 3 + 2*4 ];
        state[ 3 + 2*4 ] = state[ 3 + 3*4 ];
        state[ 3 + 3*4 ] = temp;
}

void InvMixColumns( UINT8 * state )
{
        InvMixColumn( state + 0*4 );
        InvMixColumn( state + 1*4 );
        InvMixColumn( state + 2*4 );
        InvMixColumn( state + 3*4 );
}

void XORBytes( UINT8 * bytes1,UINT8 * bytes2, UINT8 count )
{
  do
  {
    *bytes1 ^= *bytes2; // Add in GF(2), ie. XOR.
    bytes1++;
    bytes2++;
  } while( --count );
}

void CopyBytes( UINT8 * to, UINT8 * from, UINT8 count )
{
  do {
    *to = *from;
    to++;
    from++;
  } while( --count );
}

void KeyExpansion( UINT8 * expandedKey )
{
  UINT8 temp[4];
  UINT8 i;
  UINT8 Rcon[4] = { 0x01, 0x00, 0x00, 0x00 }; // Round constant.

  const UINT8 * key = kTable;

  // Copy key to start of expanded key.
  i = KEYLENGTH;
  do
  {
    *expandedKey = *key;
    expandedKey++;
    key++;
  } while( --i );

  // Prepare last 4 bytes of key in temp.
  CopyBytes(temp, expandedKey-4, 4);

  // Expand key.
  i = KEYLENGTH;
  //j = BLOCKSIZE*(ROUNDS+1) - KEYLENGTH;
  while( i < BLOCKSIZE*(ROUNDS+1) )
  {
    // Are we at the start of a multiple of the key size?
    if( (i % KEYLENGTH) == 0 )
    {
      CycleLeft( temp ); // Cycle left once.
      SubBytes( temp, 4 ); // Substitute each byte.
      XORBytes( temp, Rcon, 4 ); // Add constant in GF(2).
      *Rcon = (*Rcon << 1) ^ (*Rcon & 0x80 ? BPOLY : 0);
    }

    // Keysize larger than 24 bytes, ie. larger that 192 bits?
    #if KEYLENGTH > 24
    // Are we right past a block size?
    else if( (i % KEYLENGTH) == BLOCKSIZE ) {
      SubBytes( temp, 4 ); // Substitute each byte.
    }
    #endif

    // Add bytes in GF(2) one KEYLENGTH away.
    XORBytes( temp, expandedKey - KEYLENGTH, 4 );

    // Copy result to current 4 bytes.
    *(expandedKey++) = temp[ 0 ];
    *(expandedKey++) = temp[ 1 ];
    *(expandedKey++) = temp[ 2 ];
    *(expandedKey++) = temp[ 3 ];
    //CopyBytes(expandedKey, temp, 4);
    //expandedKey += 4;

    i += 4; // Next 4 bytes.
  }
}

void InvCipher( UINT8 * block, UINT8 * expandedKey )
{
    UINT8 i = 0, j = 0;
        UINT8 round = ROUNDS-1;
        expandedKey += BLOCKSIZE * ROUNDS;

    XORBytes( block, expandedKey, 16 );
        expandedKey -= BLOCKSIZE;

        do
        {
                InvShiftRows( block );
        InvSubBytesAndXOR( block, expandedKey, 16 );
                expandedKey -= BLOCKSIZE;
        for(i = 4, j = 0; i > 0; i--, j+=4)
          InvMixColumn( block + j );
        } while( --round );

        InvShiftRows( block );
    InvSubBytesAndXOR( block, expandedKey, 16 );
}  

void aesDecryptInit(UINT8 *key)
{
    memcpy(kTable, key, KEYLENGTH);
        powTbl = block1;
        logTbl = block2;
        CalcPowLog( powTbl, logTbl );
        sBox = tempbuf;
        CalcSBox( sBox );

        expandedKey = block1;
        KeyExpansion( expandedKey );
       
        sBoxInv = block2; // Must be block2.
        CalcSBoxInv( sBox, sBoxInv );
}       

void aesDecrypt( UINT8 * buffer, UINT8 * chainBlock )
{
  CopyBytes( tempbuf, buffer, BLOCKSIZE );
  InvCipher( buffer, expandedKey );
  XORBytes( buffer, chainBlock, BLOCKSIZE );
  CopyBytes( chainBlock, tempbuf, BLOCKSIZE );
}

/* Encrypt */
UINT8 Multiply( UINT8 num, UINT8 factor )
{
        UINT8 mask = 1;
        UINT8 result = 0;

        while( mask != 0 )
        {
                // Check bit of factor given by mask.
                if( mask & factor )
                {        // Add current multiple of num in GF(2).
                        result ^= num;
                }
                  // Shift mask to indicate next bit.
                mask <<= 1;
                // Double num.
               num = (num << 1) ^ (num & 0x80 ? BPOLY : 0);
        }
        return result;
}

UINT8 DotProduct( UINT8 * vector1, UINT8 * vector2 )
{
  UINT8 result = 0 ,i;
  for(i = 4; i > 0; i--)
  {  result ^= Multiply( *vector1++, *vector2++ );  }

  return result;
}

void MixColumn( UINT8 * column )
{
        UINT8 row[8] = {
                0x02, 0x03, 0x01, 0x01,
                0x02, 0x03, 0x01, 0x01
        }; // Prepare first row of matrix twice, to eliminate need for cycling.
        UINT8 result[4];
       
        // Take dot products of each matrix row and the column vector.
        result[0] = DotProduct( row+0, column );
        result[1] = DotProduct( row+3, column );
        result[2] = DotProduct( row+2, column );
        result[3] = DotProduct( row+1, column );

        // Copy temporary result to original column.
   CopyBytes(column, result, 4);
}

void ShiftRows( UINT8 * state )
{
        UINT8 temp;

        // Note: State is arranged column by column.

        // Cycle second row left one time.
        temp = state[ 1 + 0*4 ];
        state[ 1 + 0*4 ] = state[ 1 + 1*4 ];
        state[ 1 + 1*4 ] = state[ 1 + 2*4 ];
        state[ 1 + 2*4 ] = state[ 1 + 3*4 ];
        state[ 1 + 3*4 ] = temp;

        // Cycle third row left two times.
        temp = state[ 2 + 0*4 ];
        state[ 2 + 0*4 ] = state[ 2 + 2*4 ];
        state[ 2 + 2*4 ] = temp;
        temp = state[ 2 + 1*4 ];
        state[ 2 + 1*4 ] = state[ 2 + 3*4 ];
        state[ 2 + 3*4 ] = temp;

        // Cycle fourth row left three times, ie. right once.
        temp = state[ 3 + 3*4 ];
        state[ 3 + 3*4 ] = state[ 3 + 2*4 ];
        state[ 3 + 2*4 ] = state[ 3 + 1*4 ];
        state[ 3 + 1*4 ] = state[ 3 + 0*4 ];
        state[ 3 + 0*4 ] = temp;
}

void Cipher( UINT8 * block, UINT8 * expandedKey )
{
        UINT8 round = ROUNDS-1, i=0,j=0;

        XORBytes( block, expandedKey, 16 );
        expandedKey += BLOCKSIZE;

        do {
                SubBytes( block, 16 );
                ShiftRows( block );
    for(i = 4, j = 0; i > 0; i--, j+=4)
      MixColumn( block + j );
                XORBytes( block, expandedKey, 16 );
                expandedKey += BLOCKSIZE;
        } while( --round );

        SubBytes( block, 16 );
        ShiftRows( block );
        XORBytes( block, expandedKey, 16 );
}

void aesEncryptInit(UINT8 *key)
{
    memcpy(kTable, key, KEYLENGTH);
        powTbl = block1;
        logTbl = tempbuf;
        CalcPowLog( powTbl, logTbl );

        sBox = block2;
        CalcSBox( sBox );

        expandedKey = block1;
        KeyExpansion(expandedKey);
}

void aesEncrypt( UINT8 * buffer,UINT8 * chainBlock )
{
        XORBytes(buffer, chainBlock, BLOCKSIZE );
        Cipher(buffer, expandedKey );
        CopyBytes(chainBlock, buffer, BLOCKSIZE );
}

/* API Function */
void Init_AES(UINT8 *key, UINT8 mode)
{
   if(mode == 1)
   { aesEncryptInit(key);  }
   else
   { aesDecryptInit(key); }
}

// void Do_AES(UINT8 *obuffer,UINT8 *ibuffer, UINT16 length, UINT8 mode)
void Do_AES(UINT8 *obuffer,UINT16 length, UINT8 mode)
{
   UINT16 i = 0;
   UINT8 block[16];
   if(length& 0xF != 0x0)
   {  return;   }
  // memcpy(obuffer, ibuffer, length);
   while(i<length)
   {
      memset(block, 0x0, 16);
          if(mode == 1)
          {  aesEncrypt(obuffer+i, block); }
          else
          {  aesDecrypt(obuffer+i, block); }
      i=i+16;          
   }
}

#endif

/**********************************************************/
2009-10-10 09:58
0
雪    币: 444
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
AES算法可以简化的,没必要弄那么多函数。
2009-10-10 10:33
0
雪    币: 69
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
11
这样做的目的是主要是为了方便扩展
2009-10-10 13:20
0
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
这么长的代码应该改成word之类的下载
2009-10-10 18:29
0
雪    币: 69
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
等待邀请码啊!
2009-10-12 16:59
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
学习了,感谢楼主
2009-10-12 17:28
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
不错!
2009-12-7 11:32
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
呃,好长啊!!
不错了,谢谢!!
2009-12-7 17:32
0
游客
登录 | 注册 方可回帖
返回
//