c++实现aes加密算法,对字符串进行加密

来源:互联网 发布:看港澳台网络机顶盒 编辑:程序博客网 时间:2024/06/05 20:28
其主要功能进行实现unsigned char类型数据到char类型转化,将unsigned char结果与16进制字符串串之间的转化。代码如下:

 #ifndef AES_H

  1. #define AES_H

  2. #include <string.h>

  3. class AES
  4. {
  5. public:
  6.   AES(unsigned char* key);
  7.   virtual ~AES();
  8.   unsigned char* Cipher(unsigned char* input);
  9.   unsigned char* InvCipher(unsigned char* input);
  10.   void* Cipher(void* input,int length=0);
  11.   void* InvCipher(void* input,int length);

  12.   void Cipher(char *input, char *output);
  13.   void InvCipher(char *inut, char *output);

  14. private:
  15.   unsigned char Sbox[256];
  16.   unsigned char InvSbox[256];
  17.   unsigned char w[11][4][4];

  18.   void KeyExpansion(unsigned char* key, unsigned char w[][4][4]);
  19.   unsigned char FFmul(unsigned char a, unsigned char b);

  20.   void SubBytes(unsigned char state[][4]);
  21.   void ShiftRows(unsigned char state[][4]);
  22.   void MixColumns(unsigned char state[][4]);
  23.   void AddRoundKey(unsigned char state[][4], unsigned char k[][4]);

  24.   void InvSubBytes(unsigned char state[][4]);
  25.   void InvShiftRows(unsigned char state[][4]);
  26.   void InvMixColumns(unsigned char state[][4]);

  27.   int strToHex(const char*ch, char *hex);
  28.   int hexToStr(const char*hex, char*ch);
  29.   int ascillToValue(const char ch);
  30.   char valueToHexCh(constint value);
  31.   int getUCharLen(const unsigned char*uch);
  32.   int strToUChar(const char*ch, unsigned char*uch);
  33.   int ucharToStr(const unsigned char*uch, char *ch);
  34.   int ucharToHex(const unsigned char*uch, char *hex);
  35.   int hexToUChar(const char*hex, unsigned char*uch);
  36. };

  37. #endif // AES_H
对应的cpp文件如下:
  1. #include "aes.h"

  2. AES::AES(unsigned char* key)
  3. {
  4.   unsigned char sBox[]=
  5.   { /*  0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f*/
  6.     0x63,0x7c,0x77,0x7b,0xf2,0x6b,0x6f,0xc5,0x30,0x01,0x67,0x2b,0xfe,0xd7,0xab,0x76,/*0*/
  7.     0xca,0x82,0xc9,0x7d,0xfa,0x59,0x47,0xf0,0xad,0xd4,0xa2,0xaf,0x9c,0xa4,0x72,0xc0,/*1*/
  8.     0xb7,0xfd,0x93,0x26,0x36,0x3f,0xf7,0xcc,0x34,0xa5,0xe5,0xf1,0x71,0xd8,0x31,0x15,/*2*/
  9.     0x04,0xc7,0x23,0xc3,0x18,0x96,0x05,0x9a,0x07,0x12,0x80,0xe2,0xeb,0x27,0xb2,0x75,/*3*/
  10.     0x09,0x83,0x2c,0x1a,0x1b,0x6e,0x5a,0xa0,0x52,0x3b,0xd6,0xb3,0x29,0xe3,0x2f,0x84,/*4*/
  11.     0x53,0xd1,0x00,0xed,0x20,0xfc,0xb1,0x5b,0x6a,0xcb,0xbe,0x39,0x4a,0x4c,0x58,0xcf,/*5*/
  12.     0xd0,0xef,0xaa,0xfb,0x43,0x4d,0x33,0x85,0x45,0xf9,0x02,0x7f,0x50,0x3c,0x9f,0xa8,/*6*/
  13.     0x51,0xa3,0x40,0x8f,0x92,0x9d,0x38,0xf5,0xbc,0xb6,0xda,0x21,0x10,0xff,0xf3,0xd2,/*7*/
  14.     0xcd,0x0c,0x13,0xec,0x5f,0x97,0x44,0x17,0xc4,0xa7,0x7e,0x3d,0x64,0x5d,0x19,0x73,/*8*/
  15.     0x60,0x81,0x4f,0xdc,0x22,0x2a,0x90,0x88,0x46,0xee,0xb8,0x14,0xde,0x5e,0x0b,0xdb,/*9*/
  16.     0xe0,0x32,0x3a,0x0a,0x49,0x06,0x24,0x5c,0xc2,0xd3,0xac,0x62,0x91,0x95,0xe4,0x79,/*a*/
  17.     0xe7,0xc8,0x37,0x6d,0x8d,0xd5,0x4e,0xa9,0x6c,0x56,0xf4,0xea,0x65,0x7a,0xae,0x08,/*b*/
  18.     0xba,0x78,0x25,0x2e,0x1c,0xa6,0xb4,0xc6,0xe8,0xdd,0x74,0x1f,0x4b,0xbd,0x8b,0x8a,/*c*/
  19.     0x70,0x3e,0xb5,0x66,0x48,0x03,0xf6,0x0e,0x61,0x35,0x57,0xb9,0x86,0xc1,0x1d,0x9e,/*d*/
  20.     0xe1,0xf8,0x98,0x11,0x69,0xd9,0x8e,0x94,0x9b,0x1e,0x87,0xe9,0xce,0x55,0x28,0xdf,/*e*/
  21.     0x8c,0xa1,0x89,0x0d,0xbf,0xe6,0x42,0x68,0x41,0x99,0x2d,0x0f,0xb0,0x54,0xbb,0x16 /*f*/
  22.   };
  23.   unsigned char invsBox[256]=
  24.   { /* 0 1 2 3 4 5 6 7 8 9 a b c d e f*/
  25.     0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,/*0*/
  26.     0x7c,0xe3,0x39,0x82,0x9b,0x2f,0xff,0x87,0x34,0x8e,0x43,0x44,0xc4,0xde,0xe9,0xcb,/*1*/
  27.     0x54,0x7b,0x94,0x32,0xa6,0xc2,0x23,0x3d,0xee,0x4c,0x95,0x0b,0x42,0xfa,0xc3,0x4e,/*2*/
  28.     0x08,0x2e,0xa1,0x66,0x28,0xd9,0x24,0xb2,0x76,0x5b,0xa2,0x49,0x6d,0x8b,0xd1,0x25,/*3*/
  29.     0x72,0xf8,0xf6,0x64,0x86,0x68,0x98,0x16,0xd4,0xa4,0x5c,0xcc,0x5d,0x65,0xb6,0x92,/*4*/
  30.     0x6c,0x70,0x48,0x50,0xfd,0xed,0xb9,0xda,0x5e,0x15,0x46,0x57,0xa7,0x8d,0x9d,0x84,/*5*/
  31.     0x90,0xd8,0xab,0x00,0x8c,0xbc,0xd3,0x0a,0xf7,0xe4,0x58,0x05,0xb8,0xb3,0x45,0x06,/*6*/
  32.     0xd0,0x2c,0x1e,0x8f,0xca,0x3f,0x0f,0x02,0xc1,0xaf,0xbd,0x03,0x01,0x13,0x8a,0x6b,/*7*/
  33.     0x3a,0x91,0x11,0x41,0x4f,0x67,0xdc,0xea,0x97,0xf2,0xcf,0xce,0xf0,0xb4,0xe6,0x73,/*8*/
  34.     0x96,0xac,0x74,0x22,0xe7,0xad,0x35,0x85,0xe2,0xf9,0x37,0xe8,0x1c,0x75,0xdf,0x6e,/*9*/
  35.     0x47,0xf1,0x1a,0x71,0x1d,0x29,0xc5,0x89,0x6f,0xb7,0x62,0x0e,0xaa,0x18,0xbe,0x1b,/*a*/
  36.     0xfc,0x56,0x3e,0x4b,0xc6,0xd2,0x79,0x20,0x9a,0xdb,0xc0,0xfe,0x78,0xcd,0x5a,0xf4,/*b*/
  37.     0x1f,0xdd,0xa8,0x33,0x88,0x07,0xc7,0x31,0xb1,0x12,0x10,0x59,0x27,0x80,0xec,0x5f,/*c*/
  38.     0x60,0x51,0x7f,0xa9,0x19,0xb5,0x4a,0x0d,0x2d,0xe5,0x7a,0x9f,0x93,0xc9,0x9c,0xef,/*d*/
  39.     0xa0,0xe0,0x3b,0x4d,0xae,0x2a,0xf5,0xb0,0xc8,0xeb,0xbb,0x3c,0x83,0x53,0x99,0x61,/*e*/
  40.     0x17,0x2b,0x04,0x7e,0xba,0x77,0xd6,0x26,0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d /*f*/
  41.   };
  42.   memcpy(Sbox, sBox, 256);
  43.   memcpy(InvSbox, invsBox, 256);
  44.   KeyExpansion(key, w);
  45. }

  46. AES::~AES()
  47. {

  48. }

  49. void AES::Cipher(char*input, char *output)
  50. {
  51.   unsigned char uch_input[1024];
  52.   strToUChar(input, uch_input);
  53.   Cipher(uch_input);
  54.   ucharToHex(uch_input,output);
  55. }

  56. void AES::InvCipher(char*input, char *output)
  57. {
  58.   unsigned char uch_input[1024];
  59.   hexToUChar(input, uch_input);
  60.   InvCipher(uch_input);
  61.   ucharToStr(uch_input, output);
  62. }

  63. unsigned char* AES::Cipher(unsigned char* input)
  64. {
  65.   unsigned char state[4][4];
  66.   int i,r,c;

  67.   for(r=0; r<4; r++)
  68.   {
  69.     for(c=0; c<4;c++)
  70.     {
  71.       state[r][c]= input[c*4+r];
  72.     }
  73.   }

  74.   AddRoundKey(state,w[0]);

  75.   for(i=1; i<=10; i++)
  76.   {
  77.     SubBytes(state);
  78.     ShiftRows(state);
  79.     if(i!=10)MixColumns(state);
  80.     AddRoundKey(state,w[i]);
  81.   }

  82.   for(r=0; r<4; r++)
  83.   {
  84.     for(c=0; c<4;c++)
  85.     {
  86.       input[c*4+r]= state[r][c];
  87.     }
  88.   }

  89.   return input;
  90. }

  91. unsigned char* AES::InvCipher(unsigned char* input)
  92. {
  93.   unsigned char state[4][4];
  94.   int i,r,c;

  95.   for(r=0; r<4; r++)
  96.   {
  97.     for(c=0; c<4;c++)
  98.     {
  99.       state[r][c]= input[c*4+r];
  100.     }
  101.   }

  102.   AddRoundKey(state, w[10]);
  103.   for(i=9; i>=0; i--)
  104.   {
  105.     InvShiftRows(state);
  106.     InvSubBytes(state);
  107.     AddRoundKey(state, w[i]);
  108.     if(i)
  109.     {
  110.       InvMixColumns(state);
  111.     }
  112.   }

  113.   for(r=0; r<4; r++)
  114.   {
  115.     for(c=0; c<4;c++)
  116.     {
  117.       input[c*4+r]= state[r][c];
  118.     }
  119.   }

  120.   return input;
  121. }

  122. void* AES::Cipher(void* input,int length)
  123. {
  124.   unsigned char* in= (unsigned char*) input;
  125.   int i;
  126.   if(!length)
  127.   {
  128.     while(*(in+length++));
  129.     in = (unsigned char*) input;
  130.   }
  131.   for(i=0; i<length; i+=16)
  132.   {
  133.     Cipher(in+i);
  134.   }
  135.   return input;
  136. }

  137. void* AES::InvCipher(void* input,int length)
  138. {
  139.   unsigned char* in= (unsigned char*) input;
  140.   int i;
  141.   for(i=0; i<length; i+=16)
  142.   {
  143.     InvCipher(in+i);
  144.   }
  145.   return input;
  146. }

  147. void AES::KeyExpansion(unsigned char* key, unsigned char w[][4][4])
  148. {
  149.   int i,j,r,c;
  150.   unsigned char rc[]= {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36};
  151.   for(r=0; r<4; r++)
  152.   {
  153.     for(c=0; c<4; c++)
  154.     {
  155.       w[0][r][c]= key[r+c*4];
  156.     }
  157.   }
  158.   for(i=1; i<=10; i++)
  159.   {
  160.     for(j=0; j<4; j++)
  161.     {
  162.       unsigned char t[4];
  163.       for(r=0; r<4; r++)
  164.       {
  165.         t[r]= j ? w[i][r][j-1]: w[i-1][r][3];
  166.       }
  167.       if(j == 0)
  168.       {
  169.         unsigned char temp = t[0];
  170.         for(r=0; r<3; r++)
  171.         {
  172.           t[r]= Sbox[t[(r+1)%4]];
  173.         }
  174.         t[3]= Sbox[temp];
  175.         t[0] ^= rc[i-1];
  176.       }
  177.       for(r=0; r<4; r++)
  178.       {
  179.         w[i][r][j]= w[i-1][r][j] ^ t[r];
  180.       }
  181.     }
  182.   }
  183. }

  184. unsigned char AES::FFmul(unsigned char a, unsigned char b)
  185. {
  186.   unsigned char bw[4];
  187.   unsigned char res=0;
  188.   int i;
  189.   bw[0] = b;
  190.   for(i=1; i<4; i++)
  191.   {
  192.     bw[i] = bw[i-1]<<1;
  193.     if(bw[i-1]&0x80)
  194.     {
  195.       bw[i]^=0x1b;
  196.     }
  197.   }
  198.   for(i=0; i<4; i++)
  199.   {
  200.     if((a>>i)&0x01)
  201.     {
  202.       res ^= bw[i];
  203.     }
  204.   }
  205.   return res;
  206. }

  207. void AES::SubBytes(unsigned char state[][4])
  208. {
  209.   int r,c;
  210.   for(r=0; r<4; r++)
  211.   {
  212.     for(c=0; c<4; c++)
  213.     {
  214.       state[r][c]= Sbox[state[r][c]];
  215.     }
  216.   }
  217. }

  218. void AES::ShiftRows(unsigned char state[][4])
  219. {
  220.   unsigned char t[4];
  221.   int r,c;
  222.   for(r=1; r<4; r++)
  223.   {
  224.     for(c=0; c<4; c++)
  225.     {
  226.       t[c] = state[r][(c+r)%4];
  227.     }
  228.     for(c=0; c<4; c++)
  229.     {
  230.       state[r][c]= t[c];
  231.     }
  232.   }
  233. }

  234. void AES::MixColumns(unsigned char state[][4])
  235. {
  236.   unsigned char t[4];
  237.   int r,c;
  238.   for(c=0; c< 4; c++)
  239.   {
  240.     for(r=0; r<4; r++)
  241.     {
  242.       t[r] = state[r][c];
  243.     }
  244.     for(r=0; r<4; r++)
  245.     {
  246.       state[r][c]= FFmul(0x02, t[r])
  247.             ^ FFmul(0x03, t[(r+1)%4])
  248.             ^ FFmul(0x01, t[(r+2)%4])
  249.             ^ FFmul(0x01, t[(r+3)%4]);
  250.     }
  251.   }
  252. }

  253. void AES::AddRoundKey(unsigned char state[][4], unsigned char k[][4])
  254. {
  255.   int r,c;
  256.   for(c=0; c<4; c++)
  257.   {
  258.     for(r=0; r<4; r++)
  259.     {
  260.       state[r][c] ^= k[r][c];
  261.     }
  262.   }
  263. }

  264. void AES::InvSubBytes(unsigned char state[][4])
  265. {
  266.   int r,c;
  267.   for(r=0; r<4; r++)
  268.   {
  269.     for(c=0; c<4; c++)
  270.     {
  271.       state[r][c]= InvSbox[state[r][c]];
  272.     }
  273.   }
  274. }

  275. void AES::InvShiftRows(unsigned char state[][4])
  276. {
  277.   unsigned char t[4];
  278.   int r,c;
  279.   for(r=1; r<4; r++)
  280.   {
  281.     for(c=0; c<4; c++)
  282.     {
  283.       t[c] = state[r][(c-r+4)%4];
  284.     }
  285.     for(c=0; c<4; c++)
  286.     {
  287.       state[r][c]= t[c];
  288.     }
  289.   }
  290. }

  291. void AES::InvMixColumns(unsigned char state[][4])
  292. {
  293.   unsigned char t[4];
  294.   int r,c;
  295.   for(c=0; c< 4; c++)
  296.   {
  297.     for(r=0; r<4; r++)
  298.     {
  299.       t[r] = state[r][c];
  300.     }
  301.     for(r=0; r<4; r++)
  302.     {
  303.       state[r][c]= FFmul(0x0e, t[r])
  304.             ^ FFmul(0x0b, t[(r+1)%4])
  305.             ^ FFmul(0x0d, t[(r+2)%4])
  306.             ^ FFmul(0x09, t[(r+3)%4]);
  307.     }
  308.   }
  309. }

  310. int AES::getUCharLen(const unsigned char*uch)
  311. {
  312.   int len = 0;
  313.   while(*uch++)
  314.     ++len;

  315.   return len;
  316. }

  317. int AES::ucharToHex(const unsigned char*uch, char *hex)
  318. {
  319.   int high,low;
  320.   int tmp = 0;
  321.   if(uch == NULL || hex == NULL){
  322.     return -1;
  323.   }

  324.   if(getUCharLen(uch)== 0){
  325.     return -2;
  326.   }

  327.   while(*uch){
  328.     tmp = (int)*uch;
  329.     high = tmp >> 4;
  330.     low = tmp & 15;
  331.     *hex++= valueToHexCh(high);//先写高字节
  332.     *hex++= valueToHexCh(low);//其次写低字节
  333.     uch++;
  334.   }
  335.   *hex = '\0';
  336.   return 0;
  337. }

  338. int AES::hexToUChar(const char*hex, unsigned char*uch)
  339. {
  340.   int high,low;
  341.   int tmp = 0;
  342.   if(hex== NULL || uch== NULL){
  343.     return -1;
  344.   }

  345.   if(strlen(hex)%2 == 1){
  346.     return -2;
  347.   }

  348.   while(*hex){
  349.     high = ascillToValue(*hex);
  350.     if(high< 0){
  351.       *uch ='\0';
  352.       return -3;
  353.     }
  354.     hex++;//指针移动到下一个字符上
  355.     low = ascillToValue(*hex);
  356.     if(low < 0){
  357.       *uch ='\0';
  358.       return -3;
  359.     }
  360.     tmp = (high<< 4)+ low;
  361.     *uch++= tmp;
  362.     hex++;
  363.   }
  364.   *uch = (int)'\0';
  365.   return 0;
  366. }

  367. int AES::strToUChar(const char*ch, unsigned char*uch)
  368. {
  369.   int tmp = 0;
  370.   if(ch == NULL || uch ==NULL)
  371.     return -1;
  372.   if(strlen(ch)== 0)
  373.     return -2;

  374.   while(*ch){
  375.     tmp = (int)*ch;
  376.     *uch++= tmp;
  377.     ch++;
  378.   }
  379.   *uch = (int)'\0';
  380.   return 0;
  381. }

  382. int AES::ucharToStr(const unsigned char*uch, char *ch)
  383. {
  384.   int tmp = 0;
  385.   if(uch == NULL || ch ==NULL)
  386.     return -1;

  387.   while(*uch){
  388.     tmp = (int)*uch;
  389.     *ch++= (char)tmp;
  390.     uch++;
  391.   }
  392.   *ch = '\0';

  393.   return 0;
  394. }

  395. int AES::strToHex(const char*ch, char *hex)
  396. {
  397.   int high,low;
  398.   int tmp = 0;
  399.   if(ch == NULL || hex == NULL){
  400.     return -1;
  401.   }

  402.   if(strlen(ch)== 0){
  403.     return -2;
  404.   }

  405.   while(*ch){
  406.     tmp = (int)*ch;
  407.     high = tmp >> 4;
  408.     low = tmp & 15;
  409.     *hex++= valueToHexCh(high);//先写高字节
  410.     *hex++= valueToHexCh(low);//其次写低字节
  411.     ch++;
  412.   }
  413.   *hex = '\0';
  414.   return 0;
  415. }

  416. int AES::hexToStr(const char*hex, char*ch)
  417. {
  418.   int high,low;
  419.   int tmp = 0;
  420.   if(hex== NULL || ch== NULL){
  421.     return -1;
  422.   }

  423.   if(strlen(hex)%2 == 1){
  424.     return -2;
  425.   }

  426.   while(*hex){
  427.     high = ascillToValue(*hex);
  428.     if(high< 0){
  429.       *ch ='\0';
  430.       return -3;
  431.     }
  432.     hex++;//指针移动到下一个字符上
  433.     low = ascillToValue(*hex);
  434.     if(low < 0){
  435.       *ch ='\0';
  436.       return -3;
  437.     }
  438.     tmp = (high<< 4)+ low;
  439.     *ch++= (char)tmp;
  440.     hex++;
  441.   }
  442.   *ch = '\0';
  443.   return 0;
  444. }

  445. int AES::ascillToValue(const char ch){
  446.   int result = 0;
  447.   //获取16进制的高字节位数据
  448.   if(ch >= '0'&& ch <= '9'){
  449.     result = (int)(ch- '0');
  450.   }
  451.   else if(ch>= 'a' && ch<= 'z'){
  452.     result = (int)(ch- 'a')+ 10;
  453.   }
  454.   else if(ch>= 'A' && ch<= 'Z'){
  455.     result = (int)(ch- 'A')+ 10;
  456.   }
  457.   else{
  458.     result = -1;
  459.   }
  460.   return result;
  461. }

  462. char AES::valueToHexCh(constint value)
  463. {
  464.   char result = '\0';
  465.   if(value >= 0 && value<= 9){
  466.     result = (char)(value+ 48);//48为ascii编码的‘0’字符编码值
  467.   }
  468.   else if(value>= 10 && value <= 15){
  469.     result = (char)(value- 10 + 65);//减去10则找出其在16进制的偏移量,65为ascii的'A'的字符编码值
  470.   }
  471.   else{
  472.     ;
  473.   }

  474.   return result;
  475. }
     经过对代码的补充,这样我们在调用加密,解密时,就非常方便了,不用再考虑unsigned char类型字符串了。
直接使用char类型字符串,就好了。调用如下:

点击(此处)折叠或打开

  1. #include <QString>

  2. #include <stdio.h>
  3. #include "aes.h"

  4. int main(int argc, char*argv[])
  5. {
  6.     char mingwen[]= "http://www.baidu.com";
  7.     char miwen_hex[1024];
  8.     //char miwen_hex[]= "8FEEEFE524F8B68DC1FCA2899AC1A6B82E636F6D";
  9.     char result[1024];
  10.     unsigned char key[]= "xcysoft123";
  11.     AES aes(key);
  12.     aes.Cipher(mingwen, miwen_hex);
  13.     printf("%s\n",miwen_hex);
  14.     aes.InvCipher(miwen_hex, result);
  15.     printf("%s\n",result);
  16.     getchar();
  17.     return 0;
  18. }
0 0