AES加密算法原理及C++代码,每步均有相应代码
创始人
2025-05-31 03:56:43
0

本文借鉴了下文。

https://blog.csdn.net/weixin_46395886/article/details/113060749?spm=1001.2014.3001.5506

并修改和增加了如下功能:

  1. 修改列移位,上文的操作为列移位,本代码更正为行移位。

  1. 增加原文分快和补位功能:上文的明文只能是16位数,本文的代码可以输入任意位数明文。

下面详细介绍AES原理和对应代码

完整代码在最后

背景

本实验采用的编程语言为C++。将AES加解密的操作封装为名为”AES”的类。

下面首先简单介绍类”AES”,再逐个介绍其他实验内容。

#include 
#include 
#include 
using namespace std;
typedef unsigned char byte;//重命名 unsigned char
struct word
{byte wordKey[4];//word x,x可存储4个byte数据,索引:x.wordkey[i]
};class AES
{
public:AES(int sizeplain){SizePlain = sizeplain;initRcon();//Rcon函数};// ~AES();void setCipherKey(byte key[]);//初始化密钥including密钥扩展void setPlainText(byte plain[]);//转换明文数据类型//密钥扩展void keyExpansion(byte key[], word w[]);word rotWord(word w);// RotByte(a,b,c,d) = (b,c,d,a)word subWord(word w);// S盒变换word wordXOR(word w1, word w2);//异或//加解密void encryption();//10轮加密算法void addRoundKey(word in[], int round);//加密机:密钥与输入异或void subByte(word in[]);//字节替代void shiftRows(word in[]);//行移位void mixColumn(word in[]);//列混淆byte GFMultiplyByte(byte L, byte R);void decryption();//10轮解密void invShiftRows(word in[]);//逆行移位void invSubByte(word in[]);//逆字节替代void invMixColumn(word in[]);//逆列混淆void initRcon();//构造函数,初始化Rcon[]void showWord16(word w[], int len);//输出格式:16进制数void showWordChar(word w[],int len);//输出格式:字符void showMesage(byte p[],word w[],word c[],int l3, word d[],int l4);//格式化输出void CoveringPlain(byte plain[]);void InverCover(word in[]);//去补位//成员变量int NumGroup;//明文分块后的块的数量int DifferValue;//补位的数值int SizePlain;//明文长度byte CoverPlain[200];//补位后的明文word InCoverdeCipherText[16];//解密后再去补位byte cipherKey[16];word plainText[4];//明文word cipherText[4];//密文word deCipherText[4];//解密后输出static const int Nb=4, Nk=4, Nr=10;word Rcon[11];word wordKey[44];//密钥static const byte SBox[16][16];//S盒static const byte invSBox[16][16];//逆S盒static const byte mixColumnMatrix[4][4];//列混淆常数矩阵static const byte invmixColumnMatrix[4][4];//逆列混淆常数矩阵
};

一.字节替代变换和逆字节替代变换

  1. 字节替代变换

  1. 字符串的补位

  1. 原理:AES属于分组加密算法,即把明文分为多段的独立明文块再依次进行加密,每个明文块的长度是128bit,对于长度不是128bit的整数倍的明文,其最后一个明文块不足128bit,这时需要对明文进行填充,使最后一个明文块凑够128bit,经过调查[1],填充数据的内容有至少三种选择,我们这里选择PKCS5Padding(默认)填充模式,其内容是如果明文块少于128bit,在明文块末尾补足相应数量的字符,且每个字节的值等于缺少的字符数。

综上,x补位的结果应该是”abcdefghijklmn22”

  1. 代码实现:

  1. “AES”类内完成补位操作的成员函数代码


// 补位
void AES::CoveringPlain(byte plain[]){NumGroup = SizePlain/16 + 1;DifferValue = NumGroup*16 - SizePlain;//补位for (int i = 0; i < SizePlain; i++) {CoverPlain[i] = plain[i];}for (int i = SizePlain; i < NumGroup*16; i++) {CoverPlain[i] = DifferValue + '0';}}
  1. 测试结果:

  1. 字符串的转码

  1. 原理:即编码:将输入字符转为数字,我们采用ASCII码进行转码。即用字符串对应的ASCII码进行编码

  1. 测试代码实现:

说明:将已经补位后的明文作为输入,输出其ASCII码对应的16进制数。事实上是把字符ASCII的16进制数作为我们的转码结果参与后面的操作。

测试结果:正确,a的ASCII码对应的16进制数是61。

  1. 字节替代

  1. 原理:字符转码后为8位16进制数,把高4位作为行值,低4位作为列值,取出S盒中对应的行列的元素作为输出,即为字节替代。

  1. 代码:

  1. “AES”类内完成字节替代操作的成员函数代码


//字节替代
void AES::subByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = SBox[L][R];}}
}
  1. 测试代码

  1. 测试结果:查表验证正确

  1. 逆字节替代变换

  1. 逆字节替代

  1. 原理:是字节替代的逆过程,过程为:把输入数据的高4位作为行值,低4位作为列值,取出逆S盒中对应的行列的元素作为输出。

  1. 代码:

  1. “AES”类内完成逆字节替代操作的成员函数代码

//逆字节替代
void AES::invSubByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = invSBox[L][R];}}
}
  1. 测试代码

  1. 逆转码

  1. 原理:ASCII码转为字符,在C++里字符就是以ASCII码的形式存储的,二者转换对于C++很容易实现。

  1. 测试代码:

这里有必要介绍两个成员函数:

void showWord16(word w[], int len);//输出w(w的数据类型为unsigned char)的ASCII码的十六进制形式。

void showWordChar(word w[],int len);//以字符的形式输出w(w的数据类型为unsigned char)。

  1. 测试结果:正确,回到了转码前补位后的结果。

  1. 去补位

  1. 原理:根据数组的最后一位和之前位的关系决定补位的数量和数值,从而去补位。

  1. 第16位和第15位不同,认为之前没有补位。

  1. 第16位和第16-j位相同,且值都为j,那么去掉数组的后j位。

  1. 代码:

  1. “AES”类内完成去补位操作的成员函数代码

//去补位
void AES::InverCover(word in[]){//初始化for (int i = 0; i < 4*NumGroup; i++)for (int j = 0; j < 4; j++)InCoverdeCipherText[i].wordKey[j] = in[i].wordKey[j];for (int i = 0; i < 4*NumGroup; i++) {for (int j = 0; j < 4; j++) {if(i*4+j>=SizePlain){InCoverdeCipherText[i].wordKey[j] = '\0';//抹去补位}}}
}
  1. 测试代码:正确,与明文相同。

二.行移位变换和逆行移位变换,列混合和逆列混合

  1. 行移位变换和逆行移位变换

  1. 行移位变换

  1. 原理:(1)将矩阵的第i行左移i个字节(i∈[0,3])

  1. 代码

  1. “AES”类内完成行移位变换操作的成员函数代码


//行移位
void AES::shiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
//            temp[i].wordKey[j] = in[(i+j)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(i+j)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}
  1. 测试代码

  1. 结果测试:正确

  1. 逆行移位变换

  1. 原理:将第i行(i∈[0,3])的元素循环右移i个字节

  1. 代码:

  1. “AES”类内完成逆行移位变换操作的成员函数代码

//逆行移位
void AES::invShiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
//            temp[i].wordKey[j] = in[(i-j+4)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(j-i+4)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}
  1. 测试代码

  1. 测试结果:正确

  1. 列混合和逆列混合

  1. 列混合

  1. 原理:给输入矩阵乘以一个字节矩阵,计算过程如下,其中s’是混合后矩阵,s是输入矩阵:

  1. 代码:

  1. “AES”类内完成列混淆操作的成员函数代码:列混淆由两部分组成,除了矩阵乘法外,还要定义GF(2^8)上的运算。

列混淆代码1矩阵乘法


// GF(2^8)运算
byte AES::GFMultiplyByte(byte L, byte R){byte temp[8];byte result = 0x00;temp[0] = L;int i;for(i=1; i<8; i++){if(temp[i-1] >= 0x80){temp[i] = (temp[i-1] << 1) ^ 0x1b;}else{temp[i] = temp[i-1] << 1;}}for(i=0; i<8; i++){if(int((R >> i) & 0x01) == 1){result ^= temp[i];}}return result;
}

测试代码

测试结果:正确,与手算结果一致

  1. 逆列混合

  1. 原理:是列混合的逆操作,计算过程如下,重要的是等式左边第一个常数矩阵的取值。

  1. 代码:

  1. “AES”类内完成逆列混淆操作的成员函数代码


//逆列混淆
void AES::invMixColumn(word in[]){word result[4];int i, j, k;for(i=0; i<4; i++){for(j=0; j<4; j++){result[i].wordKey[j] = GFMultiplyByte(invmixColumnMatrix[j][0], in[i].wordKey[0]);for(k=1; k<4; k++){result[i].wordKey[j] ^= GFMultiplyByte(invmixColumnMatrix[j][k], in[i].wordKey[k]);}}}//赋值for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = result[i].wordKey[j];}}
}
  1. 测试代码

  1. 测试结果:结果与列混淆之后,逆行移位后一样,正确。

三.轮密钥生成

  1. 原始密钥:

  1. 取值:“abcdefghijklmnop”

  1. 存储和扩展:细节如下。

  1. 代码:分以下四部分组成。

  1. 主体代码


// 密钥扩展
void AES::keyExpansion(byte key[], word w[]){int i=0;int j,k;word temp;while(i < Nk){for(j=0; j<4; j++){w[j].wordKey[i] = key[j+4*i];}i++;}i = Nk;while(i < Nb*(Nr+1)){temp = w[i-1];if((i%Nk) == 0){temp = rotWord(temp);temp = subWord(temp);temp = wordXOR(temp, Rcon[i / Nk]);}else if(Nk > 6 && (i%Nk) == 4){temp = subWord(temp);}w[i] = wordXOR(w[i - Nk], temp);i++;}
}
  1. RotByte函数

  1. S盒变换

  1. 异或

  1. 结果(16进制数)

  1. 测试代码

  1. 测试结果:

四.加密机和解密机

  1. 代码:

  1. 加密机:密钥与输入异或


//加密
void AES::addRoundKey(word in[], int round){int i, j;for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] ^= wordKey[i+4*round].wordKey[j];}}
}
  1. 十轮加密:加密的整体代码


//10轮加密
void AES::encryption(){int i, j ,k;for(i=0; i<4; i++){for(j=0; j<4; j++){cipherText[i].wordKey[j] = plainText[i].wordKey[j];}}// round functionaddRoundKey(cipherText, 0);for(i=1; i<10; i++){subByte(cipherText);shiftRows(cipherText);mixColumn(cipherText);addRoundKey(cipherText, i);}subByte(cipherText);shiftRows(cipherText);addRoundKey(cipherText, 10);
}
  1. 测试:

  1. 测试代码:其中不只有加密的完整操作也包括了完整解密的操作。

  1. 测试结果:能有密文解出密文,可见加解密操作正确。

  1. 解密机

  1. 原理:AES解密算法的初始轮和最后一轮(第10轮)的轮密钥分别是加密算法的最后一轮(第10轮)和初始轮的轮密钥,解密算法的第1轮到第9轮的轮密钥分别是加密算法的第9轮到第1轮的轮密钥经逆列混合变换后得到的。具体如下:

  1. 代码:十轮解密主体代码如下,具体的逆行移位、逆列混淆等操作前文已经介绍了,这里不再赘述。

完整代码:

#include 
#include 
#include 
using namespace std;
typedef unsigned char byte;//重命名 unsigned char
struct word
{byte wordKey[4];//word x,x可存储4个byte数据,索引:x.wordkey[i]
};class AES
{
public:AES(int sizeplain){SizePlain = sizeplain;initRcon();//Rcon函数};// ~AES();void setCipherKey(byte key[]);//初始化密钥including密钥扩展void setPlainText(byte plain[]);//转换明文数据类型//密钥扩展void keyExpansion(byte key[], word w[]);word rotWord(word w);// RotByte(a,b,c,d) = (b,c,d,a)word subWord(word w);// S盒变换word wordXOR(word w1, word w2);//异或//加解密void encryption();//10轮加密算法void addRoundKey(word in[], int round);//加密机:密钥与输入异或void subByte(word in[]);//字节替代void shiftRows(word in[]);//行移位void mixColumn(word in[]);//列混淆byte GFMultiplyByte(byte L, byte R);void decryption();//10轮解密void invShiftRows(word in[]);//逆行移位void invSubByte(word in[]);//逆字节替代void invMixColumn(word in[]);//逆列混淆void initRcon();//构造函数,初始化Rcon[]void showWord16(word w[], int len);//输出格式:16进制数void showWordChar(word w[],int len);//输出格式:字符void showMesage(byte p[],word w[],word c[],int l3, word d[],int l4);//格式化输出void CoveringPlain(byte plain[]);void InverCover(word in[]);//去补位//成员变量int NumGroup;//明文分块后的块的数量int DifferValue;//补位的数值int SizePlain;//明文长度byte CoverPlain[200];//补位后的明文word InCoverdeCipherText[16];//解密后再去补位byte cipherKey[16];word plainText[4];//明文word cipherText[4];//密文word deCipherText[4];//解密后输出static const int Nb=4, Nk=4, Nr=10;word Rcon[11];word wordKey[44];//密钥static const byte SBox[16][16];//S盒static const byte invSBox[16][16];//逆S盒static const byte mixColumnMatrix[4][4];//列混淆常数矩阵static const byte invmixColumnMatrix[4][4];//逆列混淆常数矩阵
};
//去补位
void AES::InverCover(word in[]){//初始化for (int i = 0; i < 4*NumGroup; i++)for (int j = 0; j < 4; j++)InCoverdeCipherText[i].wordKey[j] = in[i].wordKey[j];for (int i = 0; i < 4*NumGroup; i++) {for (int j = 0; j < 4; j++) {if(i*4+j>=SizePlain){InCoverdeCipherText[i].wordKey[j] = '\0';//抹去补位}}}
}
//展示结果的16进制
void AES::showWord16(word w[], int len){int i,j;for(i=0; iword(矩阵)
void AES::setPlainText(byte plain[]){int i;for(i=0; i<16; i++){plainText[i/4].wordKey[i%4] = plain[i];}
}// 读取密钥
void AES::setCipherKey(byte key[]){int i;for(i=0; i<16; i++){cipherKey[i] = key[i];}keyExpansion(cipherKey, wordKey);
}// 初始化Rcon
void AES::initRcon(){int i,j;for(i=0; i<4; i++)for(j=0; j<4; j++){Rcon[i].wordKey[j] = 0x0;}Rcon[1].wordKey[0] = 0x01;Rcon[2].wordKey[0] = 0x02;Rcon[3].wordKey[0] = 0x04;Rcon[4].wordKey[0] = 0x08;Rcon[5].wordKey[0] = 0x10;Rcon[6].wordKey[0] = 0x20;Rcon[7].wordKey[0] = 0x40;Rcon[8].wordKey[0] = 0x80;Rcon[9].wordKey[0] = 0x1b;Rcon[10].wordKey[0] = 0x36;
}// 初始化列混淆常数矩阵
const byte AES::mixColumnMatrix[4][4] = {{0x02, 0x03, 0x01, 0x01},{0x01, 0x02, 0x03, 0x01},{0x01, 0x01, 0x02, 0x03},{0x03, 0x01, 0x01, 0x02}
};
// 初始化逆列混淆常数矩阵
const byte AES::invmixColumnMatrix[4][4] = {{0x0e, 0x0b, 0x0d, 0x09},{0x09, 0x0e, 0x0b, 0x0d},{0x0d, 0x09, 0x0e, 0x0b},{0x0b, 0x0d, 0x09, 0x0e}
};// 初始化S盒
const byte AES::SBox[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}
};
// 初始化逆S盒
const byte AES::invSBox[16][16] = {0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
};// 密钥扩展
void AES::keyExpansion(byte key[], word w[]){int i=0;int j,k;word temp;while(i < Nk){for(j=0; j<4; j++){w[j].wordKey[i] = key[j+4*i];}i++;}i = Nk;while(i < Nb*(Nr+1)){temp = w[i-1];if((i%Nk) == 0){temp = rotWord(temp);temp = subWord(temp);temp = wordXOR(temp, Rcon[i / Nk]);}else if(Nk > 6 && (i%Nk) == 4){temp = subWord(temp);}w[i] = wordXOR(w[i - Nk], temp);i++;}
}// 扩展密钥——RotByte(a,b,c,d) = (b,c,d,a)
word AES::rotWord(word w){int i;word temp;for(i=0; i<4; i++){temp.wordKey[(i+3) % 4] = w.wordKey[i];}return temp;
}
// 扩展密钥——S盒变换
word AES::subWord(word w){int i;byte L, R;for(i=0; i<4; i++){L = w.wordKey[i] >> 4;R = w.wordKey[i] & 0x0f;w.wordKey[i] = SBox[L][R];}return w;
}
// 扩展密钥——异或
word AES::wordXOR(word w1, word w2){int i;word temp;for(i=0; i<4; i++){temp.wordKey[i] = w1.wordKey[i] ^ w2.wordKey[i];}return temp;
}//10轮加密
void AES::encryption(){int i, j ,k;for(i=0; i<4; i++){for(j=0; j<4; j++){cipherText[i].wordKey[j] = plainText[i].wordKey[j];}}// round functionaddRoundKey(cipherText, 0);for(i=1; i<10; i++){subByte(cipherText);shiftRows(cipherText);mixColumn(cipherText);addRoundKey(cipherText, i);}subByte(cipherText);shiftRows(cipherText);addRoundKey(cipherText, 10);
}//字节替代
void AES::subByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = SBox[L][R];}}
}//行移位
void AES::shiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
//            temp[i].wordKey[j] = in[(i+j)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(i+j)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}//列混淆
void AES::mixColumn(word in[]){word result[4];int i, j, k;for(i=0; i<4; i++){for(j=0; j<4; j++){result[i].wordKey[j] = GFMultiplyByte(mixColumnMatrix[j][0], in[i].wordKey[0]);for(k=1; k<4; k++){result[i].wordKey[j] ^= GFMultiplyByte(mixColumnMatrix[j][k], in[i].wordKey[k]);}}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = result[i].wordKey[j];}}
}// GF(2^8)运算
byte AES::GFMultiplyByte(byte L, byte R){byte temp[8];byte result = 0x00;temp[0] = L;int i;for(i=1; i<8; i++){if(temp[i-1] >= 0x80){temp[i] = (temp[i-1] << 1) ^ 0x1b;}else{temp[i] = temp[i-1] << 1;}}for(i=0; i<8; i++){if(int((R >> i) & 0x01) == 1){result ^= temp[i];}}return result;
}
//加密
void AES::addRoundKey(word in[], int round){int i, j;for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] ^= wordKey[i+4*round].wordKey[j];}}
}//解密
void AES::decryption(){int i, j, k;for(i=0; i<4; i++){for(j=0; j<4; j++){deCipherText[i].wordKey[j] = cipherText[i].wordKey[j];}}addRoundKey(deCipherText, 10);for(i=9; i>0; i--){invShiftRows(deCipherText);invSubByte(deCipherText);addRoundKey(deCipherText, i);invMixColumn(deCipherText);}invShiftRows(deCipherText);invSubByte(deCipherText);addRoundKey(deCipherText, 0);
}
//逆行移位
void AES::invShiftRows(word in[]){int i,j;word temp[4];for(i=0; i<4; i++){for(j=0; j<4; j++){
//            temp[i].wordKey[j] = in[(i-j+4)%4].wordKey[j];temp[i].wordKey[j] = in[i].wordKey[(j-i+4)%4];}}for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = temp[i].wordKey[j];}}
}
//逆字节替代
void AES::invSubByte(word in[]){int i,j;byte L, R;for(i=0; i<4; i++){for(j=0; j<4; j++){L = in[i].wordKey[j] >> 4;R = in[i].wordKey[j] & 0x0f;in[i].wordKey[j] = invSBox[L][R];}}
}
//逆列混淆
void AES::invMixColumn(word in[]){word result[4];int i, j, k;for(i=0; i<4; i++){for(j=0; j<4; j++){result[i].wordKey[j] = GFMultiplyByte(invmixColumnMatrix[j][0], in[i].wordKey[0]);for(k=1; k<4; k++){result[i].wordKey[j] ^= GFMultiplyByte(invmixColumnMatrix[j][k], in[i].wordKey[k]);}}}//赋值for(i=0; i<4; i++){for(j=0; j<4; j++){in[i].wordKey[j] = result[i].wordKey[j];}}
}int main(int argc, char const *argv[])
{// 测试1:字节替代变换和逆字节替代变换cout<<"------------------test1:字节替代变换和逆字节替代变换-----------------------"<word(矩阵)aesTest1.subByte(aesTest1.plainText);//字节替代for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {printf("%x ",aesTest1.plainText[i].wordKey[j]);}cout<

相关内容

热门资讯

王凤英入职小鹏3年终获股权,此... 5月7日消息,小鹏汽车披露的监管及年报信息显示,公司总裁王凤英已正式进入股东名册,入职小鹏3年后股权...
五块钱红酒卖断货,便宜红酒为何... 最近一段时间,中国的酒类消费市场可以说是显得格外奇怪,一方面,各种高端酒特别是白酒的消费量出现了明显...
财联社C50风向指数调查:4月... 财联社5月8日讯(记者 夏淑媛)新一期财联社“C50风向指数”结果显示,市场机构对4月新增人民币贷款...
央视硬刚国际足联拒掏20亿,背... 作者| 史大郎&猫哥 来源| 是史大郎&大猫财经Pro 央视这次太刚了,离世界杯开幕还有1个月,死活...
新CEO上任直接放大招!Air... 快科技5月8日消息,苹果即将上任的CEO John Ternus对未来一系列新产品充满信心,称这些设...
“特朗普拟邀英伟达、波音等CE... 据路透社当地时间5月7日报道,特朗普政府正邀请英伟达、苹果、埃克森美孚、波音等大公司首席执行官,于下...
世界杯,还能看到直播吗? 2026年美加墨世界杯距离开幕,仅剩一个多月时间。多方信息显示,中央广播电视总台(以下简称“央视”)...
机构警告AI芯片热潮风险,超威... 5月7日,据央视财经,隔夜超威半导体公司(AMD)股价飙升近19%,带动AI芯片热潮持续升温。AMD...
银行员工转走储户1800万最新... 银行员工转走储户1800万最新进展:2名储户已收到银行全部款项
原创 中... 1994年,安徽省的经济格局曾发生过一次戏剧性的转折。在那一年,一座名为安庆的城市,其国内生产总值(...
昆都仑区:政策“蓄力”消费焕新 “一台5000多元的空调,叠加‘国补’和商场的以旧换新活动,能优惠1000元左右,旧机还能免费上门拆...
乐悦置业竞得佛山顺德乐从镇一商... 观点网讯:5月6日,佛山市顺德区乐从镇一商业地块成功出让,由广东省乐悦置业有限公司竞得,乐从南区·邻...
原创 亦... 《爱情没有神话》这部剧,一开始的命运颇为多舛,经历了几次撤档的波折后,终于在观众面前亮相,但其首播的...
美联储34年最大分歧叠加油价飙... 美联储按预期维持利率不变,但内部出现34年来最严重分歧,叠加布油创2022年6月以来新高,美债遭抛售...
支付宝消费券回收后,资金是否支... 摘要: 支付宝消费券回收变现后,资金能否直接转入信用卡?本文解答到账方式的相关规则,帮助用户了解资金...
中医介绍5个化痰穴位!收藏这篇... 很多人忽略了“痰”的危害,觉得咳几下就没事,殊不知,肺里的痰长期堆积,只会一步步加重身体负担。 中医...
黄金平台“杰我睿”涉嫌经济犯罪... 红星资本局5月7日消息,深圳水贝知名金店“杰我睿”兑付困难事件有了新进展。日前,深圳市公安局罗湖分局...
多地出台购房新政促楼市升温 记... 今年的“五一”假期,伴随着多个城市楼市新政密集落地,在叠加市场信心持续修复的作用下,房地产市场热度持...
谁是五一“吸金王”?这5座城市... 来源:市场资讯 (来源:21城市观) 哪座城市成为“五一”假期的大赢家? 图源:摄图网 作者|赵晓...
“低招低裁”格局稳固劳动力市场... 智通财经APP获悉,美国上周初请失业金人数在经历前一周回落至近几十年来最低水平后出现小幅反弹,表明尽...