1 Star 0 Fork 28

郭昕灏/文件软硬件加解密平台

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
AES.cpp 16.20 KB
一键复制 编辑 原始数据 按行查看 历史
qingfengfumeng 提交于 2024-09-13 15:37 . update AES.cpp.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763
/**************************************************
* project name: AES
* author: wang binbin
* completion time: 2024.3.26
*************************************************/
#include "AES.h"
int S[16][16]; // S_box
int S2[16][16]; // S_box_inverse
int word[4][44];
static const int ColM[4][4] = // Matrix used by MixColumn
{
2, 3, 1, 1,
1, 2, 3, 1,
1, 1, 2, 3,
3, 1, 1, 2
};
static const int ColM2[4][4] = // Matrix used by inverse MixColumn
{
0x0e, 0x0b, 0x0d, 0x09,
0x09, 0x0e, 0x0b, 0x0d,
0x0d, 0x09, 0x0e, 0x0b,
0x0b, 0x0d, 0x09, 0x0e
};
static const int Rcon[10] = //KeyExpansion wheel constant
{ 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 };
static const int Cbox[8][8] = //Matrix used by generating S_box
{
1,0,0,0,1,1,1,1,
1,1,0,0,0,1,1,1,
1,1,1,0,0,0,1,1,
1,1,1,1,0,0,0,1,
1,1,1,1,1,0,0,0,
0,1,1,1,1,1,0,0,
0,0,1,1,1,1,1,0,
0,0,0,1,1,1,1,1
};
static const int Cbox2[8][8] = //Matrix used by generating inverse S_box
{
0,0,1,0,0,1,0,1,
1,0,0,1,0,0,1,0,
0,1,0,0,1,0,0,1,
1,0,1,0,0,1,0,0,
0,1,0,1,0,0,1,0,
0,0,1,0,1,0,0,1,
1,0,0,1,0,1,0,0,
0,1,0,0,1,0,1,0
};
static const int XORc[8] = { 1,1,0,0,0,1,1,0 }; // Xor constant for S-box generation
static const int XORc2[8] = { 1,0,1,0,0,0,0,0 }; // Xor constant for inverse S-box generation
/**************** Function definition ********************/
AES::AES()
{
genSbox(S);
genSbox2(S2);
};
void AES::genKey(std::string outputname)
{
cout << "生成密钥中......" << endl;
std::string key;
const std::string charset = "0123456789abcdef";
std::mt19937 gen(static_cast<unsigned int>(time(nullptr)));
std::uniform_int_distribution<int> dist(0, charset.size() - 1);
for (int i = 0; i < 32; i++)
{
key = key + charset[dist(gen)];
}
Key = key;
// Write the generated key and iv to a file
std::ofstream outputFile(outputname);
if (!outputFile.is_open())
{
std::cerr << "Unable to open output file: " << outputname << std::endl;
}
outputFile << key << std::endl;
outputFile.close();
cout << "生成的密钥已写入 " << outputname << " 中。" << endl;
}
void AES::getKey(std::string filename)
{
std::ifstream file(filename); // open file
if (!file.is_open())
{
std::cerr << "Failed to open file " << filename << "!" << std::endl;
}
else
{
if (!(std::getline(file, Key)))
{
std::cerr << "Failed to read " << filename << "!" << std::endl;
}
}
file.close(); // closed file
keyExpansion(word);
}
int AES::gfMul(int n, int m)
{
bitset<8> a(n);
bitset<8> b(m);
int nrr[8]; // store n in binary
int brr[8]; // store binary before m shift
int arr[8] = { 0 }; // store m-shifted binary
int temp[8];
int c[8] = { 0,0,0,1,1,0,1,1 };
int result = 0;
for (int i = 0; i < 8; i++)
{
brr[7 - i] = b[i];
nrr[7 - i] = a[i];
}
for (int i = 0; i < 7; i++)
{
int cnt = 0;
for (int i = 0; i < 8; i++)
{
temp[i] = brr[i];
}
if (nrr[i] == 1)
{
cnt = 7 - i;
}
while (cnt--)
{
int flag = temp[0];
for (int i = 1; i < 8; i++)
{
temp[i - 1] = temp[i];
}
temp[7] = 0;
if (flag)
{
for (int i = 0; i < 8; i++)
{
temp[i] = temp[i] ^ c[i];
}
}
}
if (nrr[i] == 1)
{
for (int i = 0; i < 8; i++)
{
arr[i] = arr[i] ^ temp[i];
}
}
}
if (nrr[7] == 1)
{
for (int i = 0; i < 8; i++)
{
arr[i] = arr[i] ^ brr[i];
}
}
for (int i = 0; i < 8; i++)
{
if (arr[i] == 1)
{
result = result + pow(2, 7 - i);
}
}
return result;
}
int AES::invElement(int m)
{
int x = 0;
for (int i = 1; i < 256; i++)
{
if (gfMul(i, m) == 1)
{
x = i;
break;
}
}
return x;
}
void AES::genSbox(int box[16][16])
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
box[i][j] = i * 16 + j;
}
}
for (int j = 1; j < 16; j++)
{
box[0][j] = invElement(box[0][j]);
}
for (int i = 1; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
box[i][j] = invElement(box[i][j]);
}
}
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
int result = 0;
bitset<8> b(box[i][j]);
int brr[8] = { 0 };
for (int i = 0; i < 8; i++)
{
for (int k = 0; k < 8; k++)
{
brr[i] = brr[i] ^ (Cbox[i][k] * b[k]);
}
}
for (int i = 0; i < 8; i++)
{
brr[i] = brr[i] ^ XORc[i];
}
for (int i = 0; i < 8; i++)
{
if (brr[i] == 1)
{
result = result + pow(2, i);
}
}
box[i][j] = result;
}
}
}
void AES::genSbox2(int box[16][16])
{
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
box[i][j] = i * 16 + j;
}
}
for (int i = 0; i < 16; i++)
{
for (int j = 0; j < 16; j++)
{
int result = 0;
bitset<8> b(box[i][j]);
int brr[8] = { 0 };
for (int i = 0; i < 8; i++)
{
for (int k = 0; k < 8; k++)
{
brr[i] = brr[i] ^ (Cbox2[i][k] * b[k]);
}
}
for (int i = 0; i < 8; i++)
{
brr[i] = brr[i] ^ XORc2[i];
}
for (int i = 0; i < 8; i++)
{
if (brr[i] == 1)
{
result = result + pow(2, i);
}
}
box[i][j] = invElement(result);
}
}
}
void AES::leftByte(int word[4])
{
int arr[4];
for (int i = 0; i < 4; i++)
{
arr[i] = word[i];
}
for (int i = 0; i < 4; i++)
{
word[i] = arr[(i + 1) % 4];
}
}
void AES::gFunction(int word[4], int round)
{
leftByte(word);
int row;
int col;
for (int i = 0; i < 4; i++)
{
row = word[i] / 16;
col = word[i] % 16;
word[i] = S[row][col];
}
word[0] = word[0] ^ Rcon[round];
}
void AES::keyExpansion(int word[4][44])
{
int key[4][4];
int cnt = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
std::string str;
str = str + Key[cnt];
str = str + Key[cnt + 1];
cnt = cnt + 2;
key[i][j] = hexToInt(str);
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
word[i][j] = key[i][j];
}
}
for (int i = 4, j = 0; i < 44; i++)
{
if (i % 4 == 0)
{
int arr[4];
for (int k = 0; k < 4; k++)
{
arr[k] = word[k][i - 1];
}
gFunction(arr, j);
for (int k = 0; k < 4; k++)
{
word[k][i] = word[k][i - 4] ^ arr[k];
}
j++;
}
else
{
for (int k = 0; k < 4; k++)
{
word[k][i] = word[k][i - 4] ^ word[k][i - 1];
}
}
}
}
void AES::subBytes(int m[4][4])
{
int row;
int col;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
row = m[i][j] / 16;
col = m[i][j] % 16;
m[i][j] = S[row][col];
}
}
}
void AES::subBytes2(int m[4][4])
{
int row;
int col;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
row = m[i][j] / 16;
col = m[i][j] % 16;
m[i][j] = S2[row][col];
}
}
}
void AES::shiftRow(int m[4][4])
{
int p[4][4];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
p[i][j] = m[i][j];
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
m[i][j] = p[i][(j + i) % 4];
}
}
}
void AES::shiftRow2(int m[4][4])
{
int p[4][4];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
p[i][j] = m[i][j];
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
int temp = j - i;
if (temp < 0)
{
temp = temp + 4;
}
m[i][j] = p[i][temp];
}
}
}
void AES::mixColumn(int m[4][4])
{
int p[4][4];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
p[i][j] = m[i][j];
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
m[i][j] = 0;
for (int k = 0; k < 4; k++)
{
m[i][j] = m[i][j] ^ gfMul(ColM[i][k], p[k][j]);
}
}
}
}
void AES::mixColumn2(int m[4][4])
{
int p[4][4];
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
p[i][j] = m[i][j];
}
}
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
m[i][j] = 0;
for (int k = 0; k < 4; k++)
{
m[i][j] = m[i][j] ^ gfMul(ColM2[i][k], p[k][j]);
}
}
}
}
void AES::addRoundKey(int m[4][4], int key[4][4])
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
m[i][j] = m[i][j] ^ key[i][j];
}
}
}
std::string AES::intToHex(int value)
{
stringstream stream;
stream << hex << setw(2) << setfill('0') << value;
return stream.str();
}
int AES::hexToInt(const std::string& hexStr)
{
std::stringstream stream(hexStr);
int value;
stream >> hex >> value;
return value;
}
void AES::encrypt(int ptext[4][4])
{
int KeyRound[4][4];
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 4; k++)
{
KeyRound[k][j] = word[k][j];
}
}
addRoundKey(ptext, KeyRound);
for (int r = 1; r <= 9; r++)
{
subBytes(ptext);
shiftRow(ptext);
mixColumn(ptext);
for (int j = r * 4, l = 0; j < r * 4 + 4; j++, l++)
{
for (int k = 0; k < 4; k++)
{
KeyRound[k][l] = word[k][j];
}
}
addRoundKey(ptext, KeyRound);
}
subBytes(ptext);
shiftRow(ptext);
for (int j = 10 * 4, l = 0; j < 10 * 4 + 4; j++, l++)
{
for (int k = 0; k < 4; k++)
{
KeyRound[k][l] = word[k][j];
}
}
addRoundKey(ptext, KeyRound);
}
void AES::decrypt(int ctext[4][4])
{
int KeyRound[4][4];
for (int j = 10 * 4, l = 0; j < 10 * 4 + 4; j++, l++)
{
for (int k = 0; k < 4; k++)
{
KeyRound[k][l] = word[k][j];
}
}
addRoundKey(ctext, KeyRound);
for (int r = 9; r >= 1; r--)
{
subBytes2(ctext);
shiftRow2(ctext);
mixColumn2(ctext);
for (int j = r * 4, l = 0; j < r * 4 + 4; j++, l++)
{
for (int k = 0; k < 4; k++)
{
KeyRound[k][l] = word[k][j];
}
}
mixColumn2(KeyRound);
addRoundKey(ctext, KeyRound);
}
subBytes2(ctext);
shiftRow2(ctext);
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 4; k++)
{
KeyRound[k][j] = word[k][j];
}
}
addRoundKey(ctext, KeyRound);
}
bool AES::encrypt_file(const string filename, const string outname)
{
std::ifstream inputFile(filename, ifstream::binary);
std::ofstream outputFile(outname, ifstream::binary);
if (!inputFile.is_open())
{
std::cerr << "Unable to open input file" << std::endl;
return false;
}
inputFile.seekg(0, std::ifstream::end); // Move the file pointer to the end of the file
std::streampos fileSize = inputFile.tellg(); // Gets the current position of the file pointer, that is, the size of the file
inputFile.seekg(0, std::ifstream::beg); // Move the file pointer back to the beginning of the file
uint64_t data_len = fileSize;
char* buffer = new char[data_len];
inputFile.read(buffer, data_len);
std::string in_str;
for (uint64_t i = 0; i < data_len; i++)
{
in_str = in_str + buffer[i];
}
// character fill
int n = 16 - data_len % 16;
std::string space_str(n, ' ');
in_str = in_str + space_str;
for (int i = 0; i < data_len + n; i = i + 16)
{
int ptext[4][4];
for (int j = 0; j < 4; j++) // read by row
{
for (int k = 0; k < 4; k++)
{
ptext[k][j] = uint8_t(in_str[(i + j * 4 + k)]);
}
}
encrypt(ptext);
std::string out_str;
for (int j = 0; j < 4; j++) // read by row
{
for (int k = 0; k < 4; k++)
{
out_str = out_str + char(ptext[k][j]);
}
}
outputFile.write(out_str.c_str(), out_str.size());
}
delete[] buffer;
inputFile.close();
outputFile.close();
return true;
}
bool AES::decrypt_file(const string filename, const string outname)
{
std::ifstream inputFile(filename, ifstream::binary);
std::ofstream outputFile(outname, ifstream::binary);
if (!inputFile.is_open())
{
std::cerr << "Unable to open input file" << std::endl;
return false;
}
inputFile.seekg(0, std::ifstream::end); // Move the file pointer to the end of the file
std::streampos fileSize = inputFile.tellg(); // Gets the current position of the file pointer, that is, the size of the file
inputFile.seekg(0, std::ifstream::beg); // Move the file pointer back to the beginning of the file
uint64_t data_len = fileSize;
outputFile << "\xEF\xBB\xBF"; // set the text encoding format to utf-8
char* buffer = new char[data_len];
inputFile.read(buffer, data_len);
std::string in_str;
for (uint64_t i = 0; i < data_len; i++)
{
in_str = in_str + buffer[i];
}
for (int i = 0; i < data_len; i = i + 16)
{
int ctext[4][4];
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 4; k++)
{
ctext[k][j] = uint8_t(in_str[(i + j * 4 + k)]);
}
}
decrypt(ctext);
std::string out_str;
for (int j = 0; j < 4; j++) // read by row
{
for (int k = 0; k < 4; k++)
{
out_str = out_str + char(ctext[k][j]);
}
}
outputFile.write(out_str.c_str(), out_str.size());
}
delete[] buffer;
inputFile.close();
outputFile.close();
return true;
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/guo-xinhao/cryptography_file_protection.git
git@gitee.com:guo-xinhao/cryptography_file_protection.git
guo-xinhao
cryptography_file_protection
文件软硬件加解密平台
master

搜索帮助