#include<string>
#include<iostream>
#include<bitset>
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<<so[jl].to_ulong();
cout<<endl;

}

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<<hex<<n.to_ulong()<<endl;
    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<<hex<<n.to_ulong()<<endl;
    return n;
}

word  SubByte(word &vv)//S盒变换
{
    byte p[4];
// cout<<hex<<vv.to_ulong()<<endl;
   // cout<<vv<<endl;
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<<row<<" "<<col<<endl;
     p[3-u] = S_Box[row][col];
//cout<<hex<<p[u].to_ulong()<<endl;
}
    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<<hex<<e[d].to_ulong()<<endl;
}
}

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<<hex<<answer.to_ulong()<<endl;
if(answer==0x80)
answer =  (x<<1)^0x1b;                                     //经验:不要把二进制倒过来看,除非对下标进行访问
else 
answer = x<<1;
//cout<<hex<<answer.to_ulong()<<endl;
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<<vtemp[i]<<endl;

//cout<<endl;

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<<hex<<temp[j].to_ulong();
// cout<<endl;
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-----------------------------------"<<endl;

string  ikey(32,'1'); //加密密钥扩展
    
string  kkey(128,'1');

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

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<<endl;
   cout<<"key["<<dec<<f/4<<"] = ";
}
cout<<hex<<gkey[f].to_ulong();  
    }
    cout<<endl;                                                       //2017-5-9 23:08

//cout<<"w["<<f<<"] = "<<gkey[f].to_ulong()<<endl;
   //cout<<Word_to_Fword(gkey,f)<<endl;
     
string  ming(32,'1');

string  mingg(128,'1');

cout<<"请输入16进制明文:"<<endl;

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<<hex<<state[io].to_ulong();
    cout<<endl;*/
    /*for(int ui = 0;ui<32;ui++)
cout<<state[0][ui];
cout<<endl;*/

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<<endl;
cout<<endl;
/*for(int kl =0;kl<16;kl++)
cout<<hex<<bstate[kl].to_ulong();
    cout<<endl;*/
    }
    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);
    
}

程序截图

//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

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

用c++实现AES基本算法相关推荐

  1. RC4算法原理、Java实现RC4加密算法、DES AES RC4算法比较

    DES AES RC4算法比较 根据密钥类型的不同,加密算法分为对称和非对称两种.对称加密系统是指加密和解密均采用同一把密钥. 对称加密算法是最常用的加密算法,优势在于算法公开,计算量小,加密效率高. ...

  2. aes解密算法 java_AES算法实现Java和JS互通加解密

    实际开发中客户端与服务端的通信内容往往需要通过密文传输,本文将介绍可以实现Java与js的互相加解密的AES加密方式 Java语言实现 public class AESTest { //static ...

  3. C++使用AES+Base64算法对文本进行加密

    使用AES算法和Base64实现具体的文本加密. 采用AES算法的CBC模式,16位秘钥,PKCS7Padding填充方案对文本进行加解密.此方案可防止一些比较关键的文本暴露,也可以用于服务器通信间的 ...

  4. java aes解密算法_使用java实现AES算法的加解密(亲测可用)

    话不多说,直接上代码 import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto ...

  5. AES GCM算法实现

    当前业界敏感信息加密使用AES较多,GCM模式兼具效率和安全性,故选择使用该模式. 注意 我们经常使用256位秘钥,因为美国的安全管控,jdk8的较老版本安全策略不支持256位秘钥,需替换jdk\jr ...

  6. AES GCM 算法

    AES-GCM算法是带认证和加密的算法,也即同时可以对给定的原文,生成加密数据和认证码. 加密方: plain_test key_128/key_256 iv/salt aad, 生成校验码的盐值 密 ...

  7. Delphi与JAVA互加解密AES算法

    搞了半天终于把这个对应的参数搞上了,话不多说,先干上代码: package com.bss.util;import java.io.UnsupportedEncodingException; impo ...

  8. 对于AES和RSA算法的结合使用以及MD5加盐注册登录时的密码加密

    RSA和AES结合使用 接上篇的RSA和AES算法加密之后,AES对称算法对数据量大的加密比较快,而RSA公私钥加密的话会影响加密效率,但是AES的加密与解密的密钥是一致的,导致密钥不能外泄,密钥在网 ...

  9. 加密芯片——AES算法特点与应用注意事项

    AES是一种区块加密标准算法,它的提出是为了升级替换原有的DES加密算法.因此它的安全强度高于DES算法.但不应片面理解,系统和数据的安全不仅与应用的加密算法有关,更与加密应用方案有关.和DES算法一 ...

最新文章

  1. 解决 wcf HTTP 无法注册 另一应用程序正在使用 TCP 端口 80
  2. web前端数组处理之扁平化数组
  3. 顶层 pom 中的 dependencies 与 dependencyManagement 区别
  4. python 抠图 锯齿_Python | 绘图中的抗锯齿
  5. java 解析http返回的xml_Java解析调用webservice服务的返回XML串详解
  6. 编译安装 zbar 时两次 make 带来的惊喜
  7. HDU3930(离散对数与原根)
  8. java中sql语句怎么把开始和结束时间作为参数写sql查询_聊一聊MyBatis 和 SQL 注入间的恩恩怨怨
  9. 长短期记忆网络_思维导图:长短期记忆模型
  10. 机房服务器维护管理规范,机房维护管理规范.pdf
  11. 高中计算机课程网页修改,高中信息技术教学贯彻新课改理念
  12. 微信小程序实现组件之间的传值
  13. 何恺明的ResNet引用量突破10万!
  14. 前端js实现从视频中提取图片帧
  15. 关于Python虚拟环境与包管理你应该知道的事
  16. Linux下基于GTK人脸识别界面设计
  17. 《华仪酒店管理系统》项目研发性总结
  18. 可以听歌玩游戏看股票背单词的ROS开发工具?小鱼:就差能点外卖了~
  19. 六大维度让你彻底明白机器视觉与计算机视觉的区别!
  20. “云+AI”沉锚,百度智能云锁定百度AI产业智能化航道

热门文章

  1. 远景在线(www.pcbeta.com):使用IE10登陆中国银行网银蓝屏或者死机的解决方案
  2. jenkins构建项目报错:java:[17,37] package xx.xx.xxx does not exist
  3. 官宣!1024 程序员节日程发布,第一代程序员求伯君将出席大会
  4. 微信小程序--在app.js 和其他页面中更改globalData的值
  5. 现代信息技术(IT)对会计模式的影响(by 杨烈飙)
  6. HTML+CSS大作业: 抗击疫情网页制作作业_疫情防控网页设计模板HTML_ 简单学生网页设_静态HTML+CSS网站制作成品...
  7. python 调用函数实现——斐波纳契数列
  8. 互联网+时代的企业应用集成平台
  9. Bad owner or permissions on C:\\Users\\XX/.ssh/config
  10. Windows Oracle ODBC驱动数据源安装配置