用c++实现AES基本算法

#include
#include
#include
using namespace std;
typedef bitset<8> byte;  
typedef bitset<32> word;
typedef bitset<128> fword;
//测试密钥:00012001710198aeda79171460153594
//测试明文:0001000101a198afda78173486153566
//结果密文:6cdd596b8f5642cbd23b47981a65422a




byte S_Box[16][16] = {  
    {0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5, 0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76},  
    {0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0, 0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0},  
    {0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC, 0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15},  
    {0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A, 0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75},  
    {0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0, 0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84},  
    {0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B, 0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF},  
    {0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85, 0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8},  
    {0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5, 0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2},  
    {0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17, 0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73},  
    {0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88, 0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB},  
    {0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C, 0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79},  
    {0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9, 0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08},  
    {0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6, 0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A},  
    {0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E, 0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E},  
{0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94, 0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF},  
    {0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68, 0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16}  
};  




void ox_to_b(string &ppx,string &ppz)              //16进制字符串转换2进制函数
{     
string ppl[32];
 for(int cv = 0;cv<32;cv++)
{
switch(ppx[cv]){
case '0': ppl[cv] = "0000";break;
case '1': ppl[cv] = "0001";break;
case '2': ppl[cv] = "0010";break;
case '3': ppl[cv] = "0011";break;
case '4': ppl[cv] = "0100";break;
case '5': ppl[cv] = "0101";break;
case '6': ppl[cv] = "0110";break;
case '7': ppl[cv] = "0111";break;
case '8': ppl[cv] = "1000";break;
case '9': ppl[cv] = "1001";break;
case 'A': ppl[cv] = "1010";break;
case 'a': ppl[cv] = "1010";break;
case 'B': ppl[cv] = "1011";break;
case 'b': ppl[cv] = "1011";break;
case 'C': ppl[cv] = "1100";break;
case 'c': ppl[cv] = "1100";break;
case 'D': ppl[cv] = "1101";break;
case 'd': ppl[cv] = "1101";break;
case 'E': ppl[cv] = "1110";break;
case 'e': ppl[cv] = "1110";break;
case 'F': ppl[cv] = "1111";break;
   default: ppl[cv] = "1111";break;//待解决:ppz+-ppl[cv]不行,或许可以调用某个string函数
}
 }

ppz = ppl[0] +ppl[1]+ppl[2]+ppl[3]+ppl[4]+ppl[5]+ppl[6]+ppl[7]+ppl[8]+ppl[9]+ppl[10]+ppl[11]+ppl[12]+ppl[13]+ppl[14]+ppl[15]+ppl[16]+ppl[17]+ppl[18]+ppl[19]+ppl[20]+ppl[21]+ppl[22]+ppl[23]+ppl[24]+ppl[25]+ppl[26]+ppl[27]+ppl[28]+ppl[29]+ppl[30]+ppl[31];
}


void PutOutState(word so[4])//输出状态                      
{


for(int jl = 0;jl<4;jl++)
cout< cout<

}


void circle(fword &s,word &v)     
{
for(int t = 0;t<32;t++)
v[t] = s[t];
}




void fword_to_word(fword &x,word y[4])//四字转化为单字
{
    fword temp;

for(int o = 0;o<4;o++)
{
temp=x>>o*32;
    circle(temp,y[3-o]);             //注意是反着放的
}
}










word Rotl(word &v,int gh)//左移函数
{
     word stemp;
word ktemp;
stemp = v>>24-gh*8;
ktemp = v<<8+gh*8;
return stemp|ktemp;
}




word Rcon[10] = {0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,   
                 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000};                     //轮常数




word byte_to_word(byte r[],int j)//状态列字节转换为字的函数
{

    word n(r[0+4*j].to_string()+r[1+4*j].to_string()+r[2+4*j].to_string()+r[3+4*j].to_string()); 
//cout<     return n;
}




word Byte_to_word(byte r[],int gg)//状态行字节转化为字的函数
{

    word n(r[0+gg].to_string()+r[4+gg].to_string()+r[8+gg].to_string()+r[12+gg].to_string()); 



//cout<     return n;
}




word  SubByte(word &vv)//S盒变换
{
    byte p[4];
// cout<    // cout< for(int u = 0;u<4;u++)
    { 
int col  =  vv[u*8]+vv[u*8+1]*2+vv[u*8+2]*4+vv[u*8+3]*8;                         //注意二进制站位和string不同
int row  =  vv[u*8+4]+vv[u*8+5]*2+vv[u*8+6]*4+vv[u*8+7]*8;
// cout<      p[3-u] = S_Box[row][col];
//cout< }
    return byte_to_word(p,0);
}


void ByteSub(word State[4])       //状态S盒变换
{
for(int g = 0;g<4;g++)
       State[g] = SubByte(State[g]);
}




void KeyExpansion(word q[] ,word e[])                   //密钥扩展函数
{
word Temp;
    for(int i=0;i<4;i++)
e[i] = q[i];
for(int d = 4;d<4*(1+10);d++)
{


   Temp = e[d-1];
if(d%4==0)
Temp=SubByte(Rotl(Temp,0))^Rcon[(d/4)-1];

e[d] = e[d-4]^Temp;
//cout< }
}


fword Word_to_Fword(word g[],int yy)//单字转化为四字函数
{
    fword jj(g[yy*4].to_string()+g[yy*4+1].to_string()+g[yy*4+2].to_string()+g[yy*4+3].to_string());
return jj;





void  Word_to_Byte(word &dc,byte nc[],int sl)                         //列移位字转字节
{
   word dtemp;
   for(int nv = 0;nv<4;nv++)
   {
      dtemp = dc>>nv*8;
  for(int lk = 0;lk<8;lk++)
      nc[3-nv+4*sl][lk] = dtemp[lk];
   }


}
void  word_to_Byte(word &dc,byte nc[],int sl)                         //行移位字转字节                      
{
   word dtemp;
   for(int nv = 0;nv<4;nv++)
   {
      dtemp = dc>>nv*8;
  for(int lk = 0;lk<8;lk++)
      nc[12-nv*4+sl][lk] = dtemp[lk];                                 //重点笔记:考虑到用string初始化的bitset对象中的二进制位和原string中的下标相反,即反序,故对下标操作需要反存放。
   }


}
void ShiftRows(byte sr[16])
{
      for(int sk = 0;sk<4;sk++)
        word_to_Byte(Rotl(Byte_to_word(sr,sk),sk-1),sr,sk);           //重点笔记:先转化为字,再左移,在返回字节
}




void AddRoundKey(word roundkey[],word roundstate[],int jk)           //轮密钥异或函数
{
   for(int ee = 0;ee<4;ee++)
  roundstate[ee]^=roundkey[jk*4+ee];
}






byte qtime(byte& x) {                                              //乘2,字节解析,类似于乘法分配律,另外根据GF(2^8)规则,若超过2^8,需要异或0x1b.
    byte answer = x&0x80;
//cout< if(answer==0x80)
answer =  (x<<1)^0x1b;                                     //经验:不要把二进制倒过来看,除非对下标进行访问
else 
answer = x<<1;
//cout< return answer;                                                //不能直接返回数值
}
byte GF(byte& a, byte& b)                                        //GF(2^8)中的乘法函数 
{
byte vtemp[8];

vtemp[0]  = a;

    for (int j = 1; j < 8; j++) {
vtemp[j] = qtime(vtemp[j - 1]);                         //这个数组里存放着所有a的移位值
}
    //for(int i = 0;i<8;i++)
//cout<
//cout<
byte mtemp(0x00);
for (int i = 0; i < 8; i++)
{
if(((b>>i)&0x01)==1)                                  //b的最后一位决定数组中的元素是否参与最后的异或
   mtemp ^= vtemp[i];
}
return mtemp;
}
void MixColumn(byte ko[16])                                   //列混合变换
{     
byte temp[16];
for(int i  = 0;i<16;i++) 
temp[i] = ko[i];                                     
// for(int j  = 0;j<16;j++)
// cout< // cout< byte  jz2(0x02);
byte  jz3(0x03);
for(int re = 0;re<4;re++)                              //矩阵乘法,参见密码学引论第93面
     {
ko[re*4+0] = GF(jz2,temp[re*4+0])^GF(jz3,temp[re*4+1])^temp[re*4+2]^temp[re*4+3];
ko[re*4+1] = temp[re*4+0]^GF(jz2,temp[re*4+1])^GF(jz3,temp[re*4+2])^temp[re*4+3];
ko[re*4+2] = temp[re*4+0]^temp[re*4+1]^GF(jz2,temp[re*4+2])^GF(jz3,temp[re*4+3]);
ko[re*4+3] = GF(jz3,temp[re*4+0])^temp[re*4+1]^temp[re*4+2]^GF(jz2,temp[re*4+3]);
     }


}


void StateTransform(word state[4],byte bstate[16])      //状态字节转化为字
{
for(int i = 0;i<4;i++)
      state[i] = byte_to_word(bstate,i);
}


void ByteTransform(word state[4],byte bstate[16])       //状态字转化为字节
{
    for(int ip = 0;ip<4;ip++)
      Word_to_Byte(state[ip],bstate,ip);
}


void main()
{     
cout<<"---------------------------------AES-128-----------------------------------"<
string  ikey(32,'1'); //加密密钥扩展
    
string  kkey(128,'1');


    cout<<"请输入16进制密钥:"<

cin>>ikey;                      //输入密钥

ox_to_b(ikey,kkey);              

fword skey(kkey);               //初始化密钥
    
word ss[4];                     
   
fword_to_word(skey,ss);         //四字密钥转化为字密钥
   
    word  gkey[4*11];


KeyExpansion(ss,gkey);         //密钥拓展


for(int f = 0;f<4*11;f++)      //输出全部密钥
{
if(f%4==0)
{
cout<    cout<<"key["<

cin>>ming;                                     //输入明文


ox_to_b(ming,mingg);                          


fword  sming(mingg);                           //初始化明文四字

word state[4];


fword_to_word(sming,state);                    //明文四字转化为字,缺个2进制转16进制string函数
  
    AddRoundKey(gkey,state,0);                     //轮密钥加
cout<<"AddRoundKey: ";
PutOutState(state);
/*for(int io = 0;io<4;io++)
cout<     cout<     /*for(int ui = 0;ui<32;ui++)
cout< cout<

    byte bstate[4*4];
    
for(int t = 1;t<10;t++)                      //第一轮到第九轮变换
{
ByteSub(state);                              //S盒变换
cout<<"SubByte:   ";
PutOutState(state);
    ByteTransform(state,bstate);


ShiftRows(bstate);                          //行移位变换
    StateTransform(state,bstate);
cout<<"ShiftRows: ";
PutOutState(state);

MixColumn(bstate);                         //列混合变变换
StateTransform(state,bstate);
    cout<<"MixColumns:";
PutOutState(state);


    AddRoundKey(gkey,state,t);                 //轮密钥加
    cout<<"AddRoundKey: ";
PutOutState(state);


ByteTransform(state,bstate);
cout< cout< /*for(int kl =0;kl<16;kl++)
cout<     cout<     }
    ByteSub(state);                                //最后一轮变换,相比第九轮少一个列混合变换
cout<<"SubByte:   ";
PutOutState(state);
    ByteTransform(state,bstate);


ShiftRows(bstate);
    StateTransform(state,bstate);
cout<<"ShiftRows: ";
PutOutState(state);


AddRoundKey(gkey,state,t);
    cout<<"AddRoundKey:";
PutOutState(state);


ByteTransform(state,bstate);
    
}

程序截图




用c++实现AES基本算法_第1张图片

用c++实现AES基本算法_第2张图片

//2017-5-12 0:14 终于差不多把AES加密搞完了,缺点还有16进制显示有时会省略0(或许用字符串输出会更好),明天加笔记。。。。。
//2017-5-12 8:30 笔记差不多完成了,总结一下,AES比DES复杂,对数学要求更高,并且这次采用的方法和之前DES的不同,之前的是大部分调用bitset类的to_string()方法,并在字符串上进行操作的
//这次AES大部分操作是直接在bitset对象上操作的,通过反复实验,发现用string初始化的bitset对象是反序存放,而对cout,to_ulong,to_string,<<,>>,&,^等操作符不受反序影响,推测应该是重载函数内部已经处理了。
//解密的等写完RSA再来写(累~~~)
//最后推荐两篇博文写的很好,收益颇多
//AES算法及实现:http://blog.csdn.net/lisonglisonglisong/article/details/41909813
//GF(2^8)乘法及实现:http://blog.csdn.net/bupt073114/article/details/27382533

//参考资料:密码学引论(张焕国 唐明编著,第三版,武汉大学出版社)

 

 

 

 

你可能感兴趣的:(学习笔记)