C++中四种加密算法之AES源代码

2020-01-06 15:58:03王冬梅

① 逆行变换-InvShiftRows()

上面讲到ShiftRows()是对矩阵的每一行进行循环左移,所以InvShiftRows()是对矩阵每一行进行循环右移。c++加密解密算法aes,c++,aes加密算法,aes加密算法实现

② 逆 S 盒变换-InvSubBytes()

与 S 盒变换一样,也是查表,查表的方式也一样,只不过查的是另外一个置换表(S-Box的逆表)。

③ 逆列变换-InvMixColumns()

与列变换的方式一样,只不过计算公式的系数矩阵发生了变化。如下图:c++加密解密算法aes,c++,aes加密算法,aes加密算法实现

好了,AES 解密到这里也讲完了。只要写出三个逆变换的函数,然后根据伪代码就很容易实现 AES 解密算法了。

三、C++实现

下面我用 C++ 实现 AES 的加密和解密算法,并实现了对文件的加密和解密。这里我使用 C++ STL 的bitset定义了两个类型:byte和word。需要提到的是,对于有限域上的乘法,我们既可以通过查表(6个结果表),也可以写一个函数来实现。当然,查表的效率会更高,但考虑到贴代码,这里我就用一个函数来实现的。

下面是 AES-128 对一个 128 位数据加密和解密的源代码:


/*************************************************************************  
  > File Name: AEScpp 
  > Author: SongLee  
  > E-mail: lisongshine@qqcom  
  > Created Time: 2014年12月12日 星期五 20时15分50秒  
  > Personal Blog: http://www.easck.com/>

可见,测试结果和预期输出相同,表明对数据的加密和解密成功!!!

下面我们来写 AES 对文件的加密和解密,在对 128 位的数据加解密成功以后,对文件的加解密就很简单了!只需要每次读 128 位,加密以后,将 128 位的密文写入另外一个文件…如此循环,直到文件尾。下面是对一张图片进行 AES 加密和解密的测试代码(效率先不管了,有时间我再优化):


//#include <fstream> 
typedef bitset<8> byte; 
typedef bitset<32> word; 
/** 
 * 将一个char字符数组转化为二进制 
 * 存到一个 byte 数组中 
 */ 
void charToByte(byte out[16], const char s[16]) 
{  
  for(int i=0; i<16; ++i)  
    for(int j=0; j<8; ++j)  
      out[i][j]= ((s[i]>>j) & 1);  
} 
 
/** 
 * 将连续的128位分成16组,存到一个 byte 数组中 
 */ 
void divideToByte(byte out[16], bitset<128>& data) 
{ 
  bitset<128> temp; 
  for(int i=0; i<16; ++i) 
  { 
    temp = (data << 8*i) >> 120; 
    out[i] = tempto_ulong(); 
  } 
} 
 
/** 
 * 将16个 byte 合并成连续的128位 
 */ 
bitset<128> mergeByte(byte in[16]) 
{ 
  bitset<128> res; 
  resreset(); // 置0 
  bitset<128> temp; 
  for(int i=0; i<16; ++i) 
  { 
    temp = in[i]to_ulong(); 
    temp <<= 8*(15-i); 
    res |= temp; 
  } 
  return res; 
} 
 
int main() 
{ 
  string keyStr = "abcdefghijklmnop"; 
  byte key[16];  
  charToByte(key, keyStrc_str()); 
  // 密钥扩展 
  word w[4*(Nr+1)]; 
  KeyExpansion(key, w); 
 
  bitset<128> data; 
  byte plain[16]; 
  // 将文件 flowerjpg 加密到 ciphertxt 中 
  ifstream in; 
  ofstream out; 
  inopen("D://flowerjpg", ios::binary); 
  outopen("D://ciphertxt", ios::binary); 
  while(inread((char*)&data, sizeof(data))) 
  { 
    divideToByte(plain, data); 
    encrypt(plain, w); 
    data = mergeByte(plain); 
    outwrite((char*)&data, sizeof(data)); 
    datareset(); // 置0 
  } 
  inclose(); 
  outclose(); 
 
  // 解密 ciphertxt,并写入图片 flowerjpg 
  inopen("D://ciphertxt", ios::binary); 
  outopen("D://flowerjpg", ios::binary); 
  while(inread((char*)&data, sizeof(data))) 
  { 
    divideToByte(plain, data); 
    decrypt(plain, w); 
    data = mergeByte(plain); 
    outwrite((char*)&data, sizeof(data)); 
    datareset(); // 置0 
  } 
  inclose(); 
  outclose(); 
 
  return 0; 
}