首页 > 其他分享 >网络安全实验一 分组密码实验(AES加解密)

网络安全实验一 分组密码实验(AES加解密)

时间:2024-07-17 17:30:09浏览次数:10  
标签:AES 加密 temp arr int 加解密 mtx 实验 byte

本实验代码附在文末

实验目的与要求:

  1. 理解对称密码体制和分组密码算法的基本思想
  2. 理解分组密码AES的基本原理
  3. 实现AES的加解密过程,可以对各种文件(word、txt、mp3、jpg)进行加解密
  4. 实现分组密码的密码分组链接工作模式与计算器工作模式

实验环境:

Microsoft Visual Studio 2022等

实验原理:

简单描述AES的实现原理,给出流程图

AES,全称为高级加密标准,是一种采用对称密钥的加密技术,它被设计来取代较旧的DES加密算法。AES加密过程基于将明文数据分成128位的区块,并使用相同的密钥进行加密。该过程包括多个步骤,旨在确保加密结果的安全性和难以逆向破解。

AES的加密过程涉及以下四个关键操作:

  • 字节替代(SubBytes):这是一个非线性过程,它通过一个预定的查找表将每个字节替换为另一个,从而在明文和密文之间引入非线性混淆。
  • 行移位(ShiftRows):此操作通过循环移动每一行的字节来重新排列数据,这有助于打乱明文的结构,增加密文的复杂性。
  • 列混淆(MixColumns):通过将每一列视为一个多项式,并与一个预定义的多项式进行模2乘法,进一步混淆数据,这增强了密文的随机性。
  • 轮密钥加(AddRoundKey):在这一步骤中,当前轮的密钥与数据进行异或操作,这是确保加密过程安全性的核心机制。轮密钥是从主密钥通过一系列复杂的变换衍生出来的。

除了上述操作,AES中的密钥扩展机制同样至关重要。它负责从原始密钥生成多个轮密钥,确保每一轮加密都有不同的密钥参与,这通过一系列操作实现,如Rcon、SubWord和RotWord等。

AES的安全性源自其复杂的替代和置换网络,以及密钥扩展的不可预测性。没有正确的密钥,攻击者极难解密AES加密的数据,因为这通常需要尝试所有可能的密钥组合,这是一个计算上非常密集且耗时的过程。AES算法以其高度的安全性和效率,已成为当今世界最广泛使用的加密标准之一。

图 1 AES算法流程图

实验内容:

  1. 熟悉AES的加解密过程
  2. 采用自己熟悉的编程语言实现AES加密算法
  3. 将编写的AES用于加密各种文件(word、txt、mp3、jpg),并能成功解密
  4. 实现分组密码的密码分组链接工作模式与计算器工作模式

实验步骤与结果:

  1. AES加密算法的实现及介绍

首先定义在算法过程中需要用到的表或者常量,包括S盒、逆S盒、轮常数表以及有限域GF(28)上的乘法表。

接着是定义各个加密的变换函数,声明在头文件,如图1-1所示。加密的变换函数包括:

  • SubBytes:S盒变换
  • ShiftRows:行变换
  • GFMul:有限域上的乘法
  • MixColumns:列变换
  • AddRoundKey:轮密钥加变换即将每一列与扩展密钥进行异或

图 1- 1 加密的变换函数声明

然后定义各个解密函数,声明在头文件,如图1-2所示,解密函数包括:

  • InvSubBytes:逆S盒变换
  • InvShiftRows:逆行变换
  • InvMixColumns:逆列变换

图 1- 2 解密的变换函数声明

接着是密钥扩展部分,声明在头文件,如图1-3所示,密钥扩展函数包括:

  • Word:将四个字节转换为一组
  • RotWord:将字节循环左移
  • SubWord:对一组字节中每一各字节进行S盒变换
  • KeyExpansion:密钥扩展

图 1- 3 密钥扩展函数声明

最后加密函数和解密函数的定义和声明,如图1-4所示。

图 1- 4 加密函数(左)解密函数(右)定义

编写主函数,使用测试加密效果,输出结果正确,如图1-5所示。

图 1- 5 测试AES加解密效果

  1. AES用于加密各种文件(word、txt、mp3、jpg)的截图

编写主函数,使其读入各种文件进行加密后将密文存入“gb.txt”中,再读取“gb.txt”进行解密,将解密结果存入out文件。若out文件与原文件相同说明加密算法无误。编写辅助函数进行字节操作,如图2-1所示。

图 2- 1 字节操作辅助函数

JPG:

图 2- 2 JPG文件加解密测试结果

密文示例如图2-3所示(UTF-8):

图 2- 3 密文展示

TXT:

图 2- 4 TXT文件加解密测试结果

Word:

图 2- 5 Word文件加解密测试结果

MP3:

图 2- 6 MP3文件加解密测试结果

  1. 各种分组密码多种工作模式关键代码切图及简单介绍

分组密码是一种将明文按照一定长度进行分组后,通过密钥进行加密的加密方式。而分组密码的工作模式则是指在加密过程中,每一个明文分组与密钥的组合方式。以下是五种常见的分组密码工作模式:

  • 电子密码本模式(Electronic CodebookECB 该模式是最简单的分组密码工作模式,将明文按照固定长度进行分组,每个明文分组与相应的密钥一一对应进行加密。但是,由于相同的明文分组加密后的密文是固定的,因此该模式存在重放攻击的风险。适用于数据较少的情形,加密前需要把明文数据填充到块大小的整倍数。该模式加解密图解如图3-1所示。

图 3- 1 ECB模式

  • CBC(Cipher Block Chaining, 密码块链)模式中每一个分组要先和前一个分组加密后的数据进行XOR异或操作,然后再进行加密。

这样每个密文块依赖该块之前的所有明文块,为了保持每条消息都具有唯一性,第一个数据块进行加密之前需要用初始化向量IV进行异或操作。

CBC模式是一种最常用的加密模式,它主要缺点是加密是连续的,不能并行处理,并且与ECB一样消息块必须填充到块大小的整倍数。该模式加解密图解如图3-2所示。

图 3- 2 CBC模式

  • CFB(Cipher Feedback, 密码反馈)模式和CBC模式比较相似,前一个分组的密文加密后和当前分组的明文XOR异或操作生成当前分组的密文。CFB模式的解密和CBC模式的加密在流程上其实是非常相似的。该模式加解密图解如图3-3所示。

图 3- 3 CFB 模式

  • OFB(Output Feedback, 输出反馈)模式将分组密码转换为同步流密码,也就是说可以根据明文长度先独立生成相应长度的流密码。通过流程图可以看出,OFB和CFB非常相似,CFB是前一个分组的密文加密后XOR当前分组明文,OFB是前一个分组与前一个明文块异或之前的流密码XOR当前分组明文。由于异或操作的对称性,OFB模式的解密和加密完全一样的流程。该模式加解密图解如图3-4所示。

图 3- 4 OFB模式

  • CTR(Counter, 计数器)模式与OFB模式一样,计数器模式将分组密码转换为流密码。它通过加密“计数器”的连续值来产生下一个密钥流块。该模式流程如图3-5所示。

图 3- 5 CTR模式

实验结论:

在本次实验中,我深入探索了AES加密算法的代码实现,并通过一系列测试,评估了它在加密多种文件类型时的性能表现。AES作为一种采用对称密钥的加密技术,通过一系列复杂的迭代过程,包括字节替代、行移位、列混淆和轮密钥加等步骤,极大地增强了数据的安全性。

我对分组密码的五种工作模式进行了详尽的比较分析,关注了它们在安全性、执行时间和可扩展性三个关键维度上的表现:

  • 安全性对比:我发现ECB模式由于缺少初始向量(IV),导致其安全性最低,容易受到模式分析攻击。相比之下,CBC、CFB、OFB和CTR模式都引入了IV,从而提高了加密的随机性和安全性。特别是CTR模式,它不仅增强了安全性,还允许并行处理,提升了加密效率。
  • 运行时间分析:实验结果显示,在处理不同文件加密时,CTR模式展现出了最快的加密速度,而ECB模式则相对较慢。这与预期相符,因为CTR模式支持并行处理,而ECB模式则需按顺序逐块加密。
  • 可扩展性评估:在可扩展性方面,CTR模式以其对数据块长度的灵活性和预先计算能力,表现出了最佳的扩展潜力。与之相比,ECB、CBC、CFB和OFB模式则要求数据块具有固定长度,并且在处理时依赖于前序块或输出。

通过本次实验,我对AES算法及其不同工作模式有了更深刻的理解。我坚信,凭借其高效率和强大的安全性,AES算法在保护信息安全方面发挥着至关重要的作用,并将继续在该领域内得到广泛应用。

C++代码:

#include <iostream>
#include <bitset>
#include <string>
#include <ctime>

using namespace std;
typedef bitset<8> byte;
typedef bitset<32> word;

const int Nr = 10;  // AES-128需要 10 轮加密
const int Nk = 4;   // Nk 表示输入密钥的 word 个数

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}
};

byte Inv_S_Box[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}
};

// 轮常数,密钥扩展中用到。(AES-128只需要10轮)
word Rcon[10] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000,
                 0x20000000, 0x40000000, 0x80000000, 0x1b000000, 0x36000000 };
byte Mul_02[256] = {
        0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
        0x20, 0x22, 0x24, 0x26, 0x28, 0x2a, 0x2c, 0x2e, 0x30, 0x32, 0x34, 0x36, 0x38, 0x3a, 0x3c, 0x3e,
        0x40, 0x42, 0x44, 0x46, 0x48, 0x4a, 0x4c, 0x4e, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5a, 0x5c, 0x5e,
        0x60, 0x62, 0x64, 0x66, 0x68, 0x6a, 0x6c, 0x6e, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7e,
        0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c, 0x8e, 0x90, 0x92, 0x94, 0x96, 0x98, 0x9a, 0x9c, 0x9e,
        0xa0, 0xa2, 0xa4, 0xa6, 0xa8, 0xaa, 0xac, 0xae, 0xb0, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe,
        0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde,
        0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0xfe,
        0x1b, 0x19, 0x1f, 0x1d, 0x13, 0x11, 0x17, 0x15, 0x0b, 0x09, 0x0f, 0x0d, 0x03, 0x01, 0x07, 0x05,
        0x3b, 0x39, 0x3f, 0x3d, 0x33, 0x31, 0x37, 0x35, 0x2b, 0x29, 0x2f, 0x2d, 0x23, 0x21, 0x27, 0x25,
        0x5b, 0x59, 0x5f, 0x5d, 0x53, 0x51, 0x57, 0x55, 0x4b, 0x49, 0x4f, 0x4d, 0x43, 0x41, 0x47, 0x45,
        0x7b, 0x79, 0x7f, 0x7d, 0x73, 0x71, 0x77, 0x75, 0x6b, 0x69, 0x6f, 0x6d, 0x63, 0x61, 0x67, 0x65,
        0x9b, 0x99, 0x9f, 0x9d, 0x93, 0x91, 0x97, 0x95, 0x8b, 0x89, 0x8f, 0x8d, 0x83, 0x81, 0x87, 0x85,
        0xbb, 0xb9, 0xbf, 0xbd, 0xb3, 0xb1, 0xb7, 0xb5, 0xab, 0xa9, 0xaf, 0xad, 0xa3, 0xa1, 0xa7, 0xa5,
        0xdb, 0xd9, 0xdf, 0xdd, 0xd3, 0xd1, 0xd7, 0xd5, 0xcb, 0xc9, 0xcf, 0xcd, 0xc3, 0xc1, 0xc7, 0xc5,
        0xfb, 0xf9, 0xff, 0xfd, 0xf3, 0xf1, 0xf7, 0xf5, 0xeb, 0xe9, 0xef, 0xed, 0xe3, 0xe1, 0xe7, 0xe5
};

byte Mul_03[256] = {
        0x00, 0x03, 0x06, 0x05, 0x0c, 0x0f, 0x0a, 0x09, 0x18, 0x1b, 0x1e, 0x1d, 0x14, 0x17, 0x12, 0x11,
        0x30, 0x33, 0x36, 0x35, 0x3c, 0x3f, 0x3a, 0x39, 0x28, 0x2b, 0x2e, 0x2d, 0x24, 0x27, 0x22, 0x21,
        0x60, 0x63, 0x66, 0x65, 0x6c, 0x6f, 0x6a, 0x69, 0x78, 0x7b, 0x7e, 0x7d, 0x74, 0x77, 0x72, 0x71,
        0x50, 0x53, 0x56, 0x55, 0x5c, 0x5f, 0x5a, 0x59, 0x48, 0x4b, 0x4e, 0x4d, 0x44, 0x47, 0x42, 0x41,
        0xc0, 0xc3, 0xc6, 0xc5, 0xcc, 0xcf, 0xca, 0xc9, 0xd8, 0xdb, 0xde, 0xdd, 0xd4, 0xd7, 0xd2, 0xd1,
        0xf0, 0xf3, 0xf6, 0xf5, 0xfc, 0xff, 0xfa, 0xf9, 0xe8, 0xeb, 0xee, 0xed, 0xe4, 0xe7, 0xe2, 0xe1,
        0xa0, 0xa3, 0xa6, 0xa5, 0xac, 0xaf, 0xaa, 0xa9, 0xb8, 0xbb, 0xbe, 0xbd, 0xb4, 0xb7, 0xb2, 0xb1,
        0x90, 0x93, 0x96, 0x95, 0x9c, 0x9f, 0x9a, 0x99, 0x88, 0x8b, 0x8e, 0x8d, 0x84, 0x87, 0x82, 0x81,
        0x9b, 0x98, 0x9d, 0x9e, 0x97, 0x94, 0x91, 0x92, 0x83, 0x80, 0x85, 0x86, 0x8f, 0x8c, 0x89, 0x8a,
        0xab, 0xa8, 0xad, 0xae, 0xa7, 0xa4, 0xa1, 0xa2, 0xb3, 0xb0, 0xb5, 0xb6, 0xbf, 0xbc, 0xb9, 0xba,
        0xfb, 0xf8, 0xfd, 0xfe, 0xf7, 0xf4, 0xf1, 0xf2, 0xe3, 0xe0, 0xe5, 0xe6, 0xef, 0xec, 0xe9, 0xea,
        0xcb, 0xc8, 0xcd, 0xce, 0xc7, 0xc4, 0xc1, 0xc2, 0xd3, 0xd0, 0xd5, 0xd6, 0xdf, 0xdc, 0xd9, 0xda,
        0x5b, 0x58, 0x5d, 0x5e, 0x57, 0x54, 0x51, 0x52, 0x43, 0x40, 0x45, 0x46, 0x4f, 0x4c, 0x49, 0x4a,
        0x6b, 0x68, 0x6d, 0x6e, 0x67, 0x64, 0x61, 0x62, 0x73, 0x70, 0x75, 0x76, 0x7f, 0x7c, 0x79, 0x7a,
        0x3b, 0x38, 0x3d, 0x3e, 0x37, 0x34, 0x31, 0x32, 0x23, 0x20, 0x25, 0x26, 0x2f, 0x2c, 0x29, 0x2a,
        0x0b, 0x08, 0x0d, 0x0e, 0x07, 0x04, 0x01, 0x02, 0x13, 0x10, 0x15, 0x16, 0x1f, 0x1c, 0x19, 0x1a
};

byte Mul_09[256] = {
        0x00, 0x09, 0x12, 0x1b, 0x24, 0x2d, 0x36, 0x3f, 0x48, 0x41, 0x5a, 0x53, 0x6c, 0x65, 0x7e, 0x77,
        0x90, 0x99, 0x82, 0x8b, 0xb4, 0xbd, 0xa6, 0xaf, 0xd8, 0xd1, 0xca, 0xc3, 0xfc, 0xf5, 0xee, 0xe7,
        0x3b, 0x32, 0x29, 0x20, 0x1f, 0x16, 0x0d, 0x04, 0x73, 0x7a, 0x61, 0x68, 0x57, 0x5e, 0x45, 0x4c,
        0xab, 0xa2, 0xb9, 0xb0, 0x8f, 0x86, 0x9d, 0x94, 0xe3, 0xea, 0xf1, 0xf8, 0xc7, 0xce, 0xd5, 0xdc,
        0x76, 0x7f, 0x64, 0x6d, 0x52, 0x5b, 0x40, 0x49, 0x3e, 0x37, 0x2c, 0x25, 0x1a, 0x13, 0x08, 0x01,
        0xe6, 0xef, 0xf4, 0xfd, 0xc2, 0xcb, 0xd0, 0xd9, 0xae, 0xa7, 0xbc, 0xb5, 0x8a, 0x83, 0x98, 0x91,
        0x4d, 0x44, 0x5f, 0x56, 0x69, 0x60, 0x7b, 0x72, 0x05, 0x0c, 0x17, 0x1e, 0x21, 0x28, 0x33, 0x3a,
        0xdd, 0xd4, 0xcf, 0xc6, 0xf9, 0xf0, 0xeb, 0xe2, 0x95, 0x9c, 0x87, 0x8e, 0xb1, 0xb8, 0xa3, 0xaa,
        0xec, 0xe5, 0xfe, 0xf7, 0xc8, 0xc1, 0xda, 0xd3, 0xa4, 0xad, 0xb6, 0xbf, 0x80, 0x89, 0x92, 0x9b,
        0x7c, 0x75, 0x6e, 0x67, 0x58, 0x51, 0x4a, 0x43, 0x34, 0x3d, 0x26, 0x2f, 0x10, 0x19, 0x02, 0x0b,
        0xd7, 0xde, 0xc5, 0xcc, 0xf3, 0xfa, 0xe1, 0xe8, 0x9f, 0x96, 0x8d, 0x84, 0xbb, 0xb2, 0xa9, 0xa0,
        0x47, 0x4e, 0x55, 0x5c, 0x63, 0x6a, 0x71, 0x78, 0x0f, 0x06, 0x1d, 0x14, 0x2b, 0x22, 0x39, 0x30,
        0x9a, 0x93, 0x88, 0x81, 0xbe, 0xb7, 0xac, 0xa5, 0xd2, 0xdb, 0xc0, 0xc9, 0xf6, 0xff, 0xe4, 0xed,
        0x0a, 0x03, 0x18, 0x11, 0x2e, 0x27, 0x3c, 0x35, 0x42, 0x4b, 0x50, 0x59, 0x66, 0x6f, 0x74, 0x7d,
        0xa1, 0xa8, 0xb3, 0xba, 0x85, 0x8c, 0x97, 0x9e, 0xe9, 0xe0, 0xfb, 0xf2, 0xcd, 0xc4, 0xdf, 0xd6,
        0x31, 0x38, 0x23, 0x2a, 0x15, 0x1c, 0x07, 0x0e, 0x79, 0x70, 0x6b, 0x62, 0x5d, 0x54, 0x4f, 0x46
};

byte Mul_0b[256] = {
        0x00, 0x0b, 0x16, 0x1d, 0x2c, 0x27, 0x3a, 0x31, 0x58, 0x53, 0x4e, 0x45, 0x74, 0x7f, 0x62, 0x69,
        0xb0, 0xbb, 0xa6, 0xad, 0x9c, 0x97, 0x8a, 0x81, 0xe8, 0xe3, 0xfe, 0xf5, 0xc4, 0xcf, 0xd2, 0xd9,
        0x7b, 0x70, 0x6d, 0x66, 0x57, 0x5c, 0x41, 0x4a, 0x23, 0x28, 0x35, 0x3e, 0x0f, 0x04, 0x19, 0x12,
        0xcb, 0xc0, 0xdd, 0xd6, 0xe7, 0xec, 0xf1, 0xfa, 0x93, 0x98, 0x85, 0x8e, 0xbf, 0xb4, 0xa9, 0xa2,
        0xf6, 0xfd, 0xe0, 0xeb, 0xda, 0xd1, 0xcc, 0xc7, 0xae, 0xa5, 0xb8, 0xb3, 0x82, 0x89, 0x94, 0x9f,
        0x46, 0x4d, 0x50, 0x5b, 0x6a, 0x61, 0x7c, 0x77, 0x1e, 0x15, 0x08, 0x03, 0x32, 0x39, 0x24, 0x2f,
        0x8d, 0x86, 0x9b, 0x90, 0xa1, 0xaa, 0xb7, 0xbc, 0xd5, 0xde, 0xc3, 0xc8, 0xf9, 0xf2, 0xef, 0xe4,
        0x3d, 0x36, 0x2b, 0x20, 0x11, 0x1a, 0x07, 0x0c, 0x65, 0x6e, 0x73, 0x78, 0x49, 0x42, 0x5f, 0x54,
        0xf7, 0xfc, 0xe1, 0xea, 0xdb, 0xd0, 0xcd, 0xc6, 0xaf, 0xa4, 0xb9, 0xb2, 0x83, 0x88, 0x95, 0x9e,
        0x47, 0x4c, 0x51, 0x5a, 0x6b, 0x60, 0x7d, 0x76, 0x1f, 0x14, 0x09, 0x02, 0x33, 0x38, 0x25, 0x2e,
        0x8c, 0x87, 0x9a, 0x91, 0xa0, 0xab, 0xb6, 0xbd, 0xd4, 0xdf, 0xc2, 0xc9, 0xf8, 0xf3, 0xee, 0xe5,
        0x3c, 0x37, 0x2a, 0x21, 0x10, 0x1b, 0x06, 0x0d, 0x64, 0x6f, 0x72, 0x79, 0x48, 0x43, 0x5e, 0x55,
        0x01, 0x0a, 0x17, 0x1c, 0x2d, 0x26, 0x3b, 0x30, 0x59, 0x52, 0x4f, 0x44, 0x75, 0x7e, 0x63, 0x68,
        0xb1, 0xba, 0xa7, 0xac, 0x9d, 0x96, 0x8b, 0x80, 0xe9, 0xe2, 0xff, 0xf4, 0xc5, 0xce, 0xd3, 0xd8,
        0x7a, 0x71, 0x6c, 0x67, 0x56, 0x5d, 0x40, 0x4b, 0x22, 0x29, 0x34, 0x3f, 0x0e, 0x05, 0x18, 0x13,
        0xca, 0xc1, 0xdc, 0xd7, 0xe6, 0xed, 0xf0, 0xfb, 0x92, 0x99, 0x84, 0x8f, 0xbe, 0xb5, 0xa8, 0xa3
};

byte Mul_0d[256] = {
        0x00, 0x0d, 0x1a, 0x17, 0x34, 0x39, 0x2e, 0x23, 0x68, 0x65, 0x72, 0x7f, 0x5c, 0x51, 0x46, 0x4b,
        0xd0, 0xdd, 0xca, 0xc7, 0xe4, 0xe9, 0xfe, 0xf3, 0xb8, 0xb5, 0xa2, 0xaf, 0x8c, 0x81, 0x96, 0x9b,
        0xbb, 0xb6, 0xa1, 0xac, 0x8f, 0x82, 0x95, 0x98, 0xd3, 0xde, 0xc9, 0xc4, 0xe7, 0xea, 0xfd, 0xf0,
        0x6b, 0x66, 0x71, 0x7c, 0x5f, 0x52, 0x45, 0x48, 0x03, 0x0e, 0x19, 0x14, 0x37, 0x3a, 0x2d, 0x20,
        0x6d, 0x60, 0x77, 0x7a, 0x59, 0x54, 0x43, 0x4e, 0x05, 0x08, 0x1f, 0x12, 0x31, 0x3c, 0x2b, 0x26,
        0xbd, 0xb0, 0xa7, 0xaa, 0x89, 0x84, 0x93, 0x9e, 0xd5, 0xd8, 0xcf, 0xc2, 0xe1, 0xec, 0xfb, 0xf6,
        0xd6, 0xdb, 0xcc, 0xc1, 0xe2, 0xef, 0xf8, 0xf5, 0xbe, 0xb3, 0xa4, 0xa9, 0x8a, 0x87, 0x90, 0x9d,
        0x06, 0x0b, 0x1c, 0x11, 0x32, 0x3f, 0x28, 0x25, 0x6e, 0x63, 0x74, 0x79, 0x5a, 0x57, 0x40, 0x4d,
        0xda, 0xd7, 0xc0, 0xcd, 0xee, 0xe3, 0xf4, 0xf9, 0xb2, 0xbf, 0xa8, 0xa5, 0x86, 0x8b, 0x9c, 0x91,
        0x0a, 0x07, 0x10, 0x1d, 0x3e, 0x33, 0x24, 0x29, 0x62, 0x6f, 0x78, 0x75, 0x56, 0x5b, 0x4c, 0x41,
        0x61, 0x6c, 0x7b, 0x76, 0x55, 0x58, 0x4f, 0x42, 0x09, 0x04, 0x13, 0x1e, 0x3d, 0x30, 0x27, 0x2a,
        0xb1, 0xbc, 0xab, 0xa6, 0x85, 0x88, 0x9f, 0x92, 0xd9, 0xd4, 0xc3, 0xce, 0xed, 0xe0, 0xf7, 0xfa,
        0xb7, 0xba, 0xad, 0xa0, 0x83, 0x8e, 0x99, 0x94, 0xdf, 0xd2, 0xc5, 0xc8, 0xeb, 0xe6, 0xf1, 0xfc,
        0x67, 0x6a, 0x7d, 0x70, 0x53, 0x5e, 0x49, 0x44, 0x0f, 0x02, 0x15, 0x18, 0x3b, 0x36, 0x21, 0x2c,
        0x0c, 0x01, 0x16, 0x1b, 0x38, 0x35, 0x22, 0x2f, 0x64, 0x69, 0x7e, 0x73, 0x50, 0x5d, 0x4a, 0x47,
        0xdc, 0xd1, 0xc6, 0xcb, 0xe8, 0xe5, 0xf2, 0xff, 0xb4, 0xb9, 0xae, 0xa3, 0x80, 0x8d, 0x9a, 0x97
};

byte Mul_0e[256] = {
        0x00, 0x0e, 0x1c, 0x12, 0x38, 0x36, 0x24, 0x2a, 0x70, 0x7e, 0x6c, 0x62, 0x48, 0x46, 0x54, 0x5a,
        0xe0, 0xee, 0xfc, 0xf2, 0xd8, 0xd6, 0xc4, 0xca, 0x90, 0x9e, 0x8c, 0x82, 0xa8, 0xa6, 0xb4, 0xba,
        0xdb, 0xd5, 0xc7, 0xc9, 0xe3, 0xed, 0xff, 0xf1, 0xab, 0xa5, 0xb7, 0xb9, 0x93, 0x9d, 0x8f, 0x81,
        0x3b, 0x35, 0x27, 0x29, 0x03, 0x0d, 0x1f, 0x11, 0x4b, 0x45, 0x57, 0x59, 0x73, 0x7d, 0x6f, 0x61,
        0xad, 0xa3, 0xb1, 0xbf, 0x95, 0x9b, 0x89, 0x87, 0xdd, 0xd3, 0xc1, 0xcf, 0xe5, 0xeb, 0xf9, 0xf7,
        0x4d, 0x43, 0x51, 0x5f, 0x75, 0x7b, 0x69, 0x67, 0x3d, 0x33, 0x21, 0x2f, 0x05, 0x0b, 0x19, 0x17,
        0x76, 0x78, 0x6a, 0x64, 0x4e, 0x40, 0x52, 0x5c, 0x06, 0x08, 0x1a, 0x14, 0x3e, 0x30, 0x22, 0x2c,
        0x96, 0x98, 0x8a, 0x84, 0xae, 0xa0, 0xb2, 0xbc, 0xe6, 0xe8, 0xfa, 0xf4, 0xde, 0xd0, 0xc2, 0xcc,
        0x41, 0x4f, 0x5d, 0x53, 0x79, 0x77, 0x65, 0x6b, 0x31, 0x3f, 0x2d, 0x23, 0x09, 0x07, 0x15, 0x1b,
        0xa1, 0xaf, 0xbd, 0xb3, 0x99, 0x97, 0x85, 0x8b, 0xd1, 0xdf, 0xcd, 0xc3, 0xe9, 0xe7, 0xf5, 0xfb,
        0x9a, 0x94, 0x86, 0x88, 0xa2, 0xac, 0xbe, 0xb0, 0xea, 0xe4, 0xf6, 0xf8, 0xd2, 0xdc, 0xce, 0xc0,
        0x7a, 0x74, 0x66, 0x68, 0x42, 0x4c, 0x5e, 0x50, 0x0a, 0x04, 0x16, 0x18, 0x32, 0x3c, 0x2e, 0x20,
        0xec, 0xe2, 0xf0, 0xfe, 0xd4, 0xda, 0xc8, 0xc6, 0x9c, 0x92, 0x80, 0x8e, 0xa4, 0xaa, 0xb8, 0xb6,
        0x0c, 0x02, 0x10, 0x1e, 0x34, 0x3a, 0x28, 0x26, 0x7c, 0x72, 0x60, 0x6e, 0x44, 0x4a, 0x58, 0x56,
        0x37, 0x39, 0x2b, 0x25, 0x0f, 0x01, 0x13, 0x1d, 0x47, 0x49, 0x5b, 0x55, 0x7f, 0x71, 0x63, 0x6d,
        0xd7, 0xd9, 0xcb, 0xc5, 0xef, 0xe1, 0xf3, 0xfd, 0xa7, 0xa9, 0xbb, 0xb5, 0x9f, 0x91, 0x83, 0x8d
};

/**********************************************************************/
/*                                                                    */
/*                              AES算法实现                           */
/*                                                                    */
/**********************************************************************/

/******************************下面是加密的变换函数**********************/
/**
 *  S盒变换 - 前4位为行号,后4位为列号
 */
void SubBytes(byte mtx[4 * 4]) {
    for (int i = 0; i < 16; ++i) {
        int row = mtx[i][7] * 8 + mtx[i][6] * 4 + mtx[i][5] * 2 + mtx[i][4];
        int col = mtx[i][3] * 8 + mtx[i][2] * 4 + mtx[i][1] * 2 + mtx[i][0];
        mtx[i] = S_Box[row][col];
    }
}

/**
 *  行变换 - 按字节循环移位
 */
void ShiftRows(byte mtx[4 * 4]) {
    // 第二行循环左移一位
    byte temp = mtx[4];
    for (int i = 0; i < 3; ++i)
        mtx[i + 4] = mtx[i + 5];
    mtx[7] = temp;
    // 第三行循环左移两位
    for (int i = 0; i < 2; ++i) {
        temp = mtx[i + 8];
        mtx[i + 8] = mtx[i + 10];
        mtx[i + 10] = temp;
    }
    // 第四行循环左移三位
    temp = mtx[15];
    for (int i = 3; i > 0; --i)
        mtx[i + 12] = mtx[i + 11];
    mtx[12] = temp;
}

/**
 *  有限域上的乘法 GF(2^8)
 */
byte GFMul(byte a, byte b) {
    unsigned int value;
    memcpy(&value, &b, sizeof(b));
    if (a == 0x02) {
        //cout<<value<<" "<<b<<endl;
        return Mul_02[value];
    }
    else if (a == 0x03) {
        return Mul_03[value];
    }
    else if (a == 0x09) {
        return Mul_09[value];
    }
    else if (a == 0x0b) {
        return Mul_0b[value];
    }
    else if (a == 0x0d) {
        return Mul_0d[value];
    }
    else if (a == 0x0e) {
        return Mul_0e[value];
    }
    //
    //    byte p = 0;
    //    byte hi_bit_set;
    //    for (int counter = 0; counter < 8; counter++) {
    //        if ((b & byte(1)) != 0) {
    //            p ^= a;
    //        }
    //        hi_bit_set = (byte) (a & byte(0x80));
    //        a <<= 1;
    //        if (hi_bit_set != 0) {
    //            a ^= 0x1b; /* x^8 + x^4 + x^3 + x + 1 */
    //        }
    //        b >>= 1;
    //    }
    //    return p;
    //    return {};
}

/**
 *  列变换
 */
void MixColumns(byte mtx[4 * 4]) {
    byte arr[4];
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j)
            arr[j] = mtx[i + j * 4];

        mtx[i] = GFMul(0x02, arr[0]) ^ GFMul(0x03, arr[1]) ^ arr[2] ^ arr[3];
        mtx[i + 4] = arr[0] ^ GFMul(0x02, arr[1]) ^ GFMul(0x03, arr[2]) ^ arr[3];
        mtx[i + 8] = arr[0] ^ arr[1] ^ GFMul(0x02, arr[2]) ^ GFMul(0x03, arr[3]);
        mtx[i + 12] = GFMul(0x03, arr[0]) ^ arr[1] ^ arr[2] ^ GFMul(0x02, arr[3]);
    }
}

/**
 *  轮密钥加变换 - 将每一列与扩展密钥进行异或
 */
void AddRoundKey(byte mtx[4 * 4], word k[4]) {
    for (int i = 0; i < 4; ++i) {
        word k1 = k[i] >> 24;
        word k2 = (k[i] << 8) >> 24;
        word k3 = (k[i] << 16) >> 24;
        word k4 = (k[i] << 24) >> 24;

        mtx[i] = mtx[i] ^ byte(k1.to_ulong());
        mtx[i + 4] = mtx[i + 4] ^ byte(k2.to_ulong());
        mtx[i + 8] = mtx[i + 8] ^ byte(k3.to_ulong());
        mtx[i + 12] = mtx[i + 12] ^ byte(k4.to_ulong());
    }
}

/**************************下面是解密的逆变换函数***********************/
/**
 *  逆S盒变换
 */
void InvSubBytes(byte mtx[4 * 4]) {
    for (int i = 0; i < 16; ++i) {
        int row = mtx[i][7] * 8 + mtx[i][6] * 4 + mtx[i][5] * 2 + mtx[i][4];
        int col = mtx[i][3] * 8 + mtx[i][2] * 4 + mtx[i][1] * 2 + mtx[i][0];
        mtx[i] = Inv_S_Box[row][col];
    }
}

/**
 *  逆行变换 - 以字节为单位循环右移
 */
void InvShiftRows(byte mtx[4 * 4]) {
    // 第二行循环右移一位
    byte temp = mtx[7];
    for (int i = 3; i > 0; --i)
        mtx[i + 4] = mtx[i + 3];
    mtx[4] = temp;
    // 第三行循环右移两位
    for (int i = 0; i < 2; ++i) {
        temp = mtx[i + 8];
        mtx[i + 8] = mtx[i + 10];
        mtx[i + 10] = temp;
    }
    // 第四行循环右移三位
    temp = mtx[12];
    for (int i = 0; i < 3; ++i)
        mtx[i + 12] = mtx[i + 13];
    mtx[15] = temp;
}

void InvMixColumns(byte mtx[4 * 4]) {
    byte arr[4];
    for (int i = 0; i < 4; ++i) {
        for (int j = 0; j < 4; ++j)
            arr[j] = mtx[i + j * 4];

        mtx[i] = GFMul(0x0e, arr[0]) ^ GFMul(0x0b, arr[1]) ^ GFMul(0x0d, arr[2]) ^ GFMul(0x09, arr[3]);
        mtx[i + 4] = GFMul(0x09, arr[0]) ^ GFMul(0x0e, arr[1]) ^ GFMul(0x0b, arr[2]) ^ GFMul(0x0d, arr[3]);
        mtx[i + 8] = GFMul(0x0d, arr[0]) ^ GFMul(0x09, arr[1]) ^ GFMul(0x0e, arr[2]) ^ GFMul(0x0b, arr[3]);
        mtx[i + 12] = GFMul(0x0b, arr[0]) ^ GFMul(0x0d, arr[1]) ^ GFMul(0x09, arr[2]) ^ GFMul(0x0e, arr[3]);
    }
}

/******************************下面是密钥扩展部分***********************/
/**
 * 将4个 byte 转换为一个 word.
 */
word Word(byte& k1, byte& k2, byte& k3, byte& k4) {
    word result(0x00000000);
    word temp;
    temp = k1.to_ulong();  // K1
    temp <<= 24;
    result |= temp;
    temp = k2.to_ulong();  // K2
    temp <<= 16;
    result |= temp;
    temp = k3.to_ulong();  // K3
    temp <<= 8;
    result |= temp;
    temp = k4.to_ulong();  // K4
    result |= temp;
    return result;
}

word RotWord(word& rw) {
    word high = rw << 8;
    word low = rw >> 24;
    return high | low;
}

word SubWord(bitset<32> sw) {
    word temp;
    for (int i = 0; i < 32; i += 8) {
        int row = sw.to_ulong() & 0xf0;
        row >>= 4;
        row |= (sw.to_ulong() & 0x0f) << 4;
        int col = sw.to_ulong() & 0x0f;
        col |= (sw.to_ulong() & 0xf0) >> 4;
        byte val = S_Box[row][col];
        for (int j = 0; j < 8; ++j)
            temp[i + j] = val[j];
        sw = sw ^ bitset<32>(1);
    }
    return temp;
}

void KeyExpansion(byte key[4 * Nk], word w[4 * (Nr + 1)]) {
    word temp;
    int i = 0;
    while (i < Nk) {
        w[i] = Word(key[4 * i], key[4 * i + 1], key[4 * i + 2], key[4 * i + 3]);
        ++i;
    }

    i = Nk;

    while (i < 4 * (Nr + 1)) {
        temp = w[i - 1];
        if (i % Nk == 0)
            w[i] = w[i - Nk] ^ SubWord(RotWord(temp)) ^ Rcon[i / Nk - 1];
        else
            w[i] = w[i - Nk] ^ temp;
        ++i;
    }
}
/******************************下面是加密和解密函数**************************/
/**
 *  加密
 */
void encrypt(byte in[4 * 4], word w[4 * (Nr + 1)]) {
    word key[4];
    for (int i = 0; i < 4; ++i)
        key[i] = w[i];
    AddRoundKey(in, key);

    for (int round = 1; round < Nr; ++round) {
        SubBytes(in);
        ShiftRows(in);
        MixColumns(in);
        for (int i = 0; i < 4; ++i)
            key[i] = w[4 * round + i];
        AddRoundKey(in, key);
    }

    SubBytes(in);
    ShiftRows(in);
    for (int i = 0; i < 4; ++i)
        key[i] = w[4 * Nr + i];
    AddRoundKey(in, key);
}

/**
 *  解密
 */
void decrypt(byte in[4 * 4], word w[4 * (Nr + 1)]) {
    word key[4];
    for (int i = 0; i < 4; ++i)
        key[i] = w[4 * Nr + i];
    AddRoundKey(in, key);

    for (int round = Nr - 1; round > 0; --round) {
        InvShiftRows(in);
        InvSubBytes(in);
        for (int i = 0; i < 4; ++i)
            key[i] = w[4 * round + i];
        AddRoundKey(in, key);
        InvMixColumns(in);
    }

    InvShiftRows(in);
    InvSubBytes(in);
    for (int i = 0; i < 4; ++i)
        key[i] = w[i];
    AddRoundKey(in, key);
}

#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] = temp.to_ulong();
    }
}

/**
 *  将16个 byte 合并成连续的128位
 */
bitset<128> mergeByte(byte in[16]) {
    bitset<128> res;
    res.reset();  // 置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() {
        //byte key[16] = {0x2b, 0x7e, 0x15, 0x16,
        //                0x28, 0xae, 0xd2, 0xa6,
        //                0xab, 0xf7, 0x15, 0x88,
        //                0x09, 0xcf, 0x4f, 0x3c};
    
        //byte plain[16] = {0x32, 0x88, 0x31, 0xe0,
        //                  0x43, 0x5a, 0x31, 0x37,
        //                  0xf6, 0x30, 0x98, 0x07,
        //                  0xa8, 0x8d, 0xa2, 0x34};
         输出密钥
        //cout << "密钥是:";
        //for(auto & i : key)
        //    cout << hex << i.to_ulong() << " ";
        //word w[4*(Nr+1)];
        //KeyExpansion(key, w);
    
         输出待加密的明文
        //cout << endl << "待加密的明文:"<<endl;
        //for(int i=0; i<16; ++i)
        //{
        //    cout << hex << plain[i].to_ulong() << " ";
        //    if((i+1)%4 == 0)
        //        cout << endl;
        //}
         加密,输出密文
        //encrypt(plain, w);
        //cout << "加密后的密文:"<<endl;
        //for(int i=0; i<16; ++i)
        //{
        //    cout << hex << plain[i].to_ulong() << " ";
        //    if((i+1)%4 == 0)
        //        cout << endl;
        //}
    
    
         解密,输出明文
        //decrypt(plain, w);
        //cout << "解密后的明文:"<<endl;
        //for(int i=0; i<16; ++i)
        //{
        //    cout << hex << plain[i].to_ulong() << " ";
        //    if((i+1)%4 == 0)
        //        cout << endl;
        //}
    
        //return 0;

    clock_t t = clock();
    string keyStr = "abcdefghijklmnop";
    byte key[16];
    charToByte(key, keyStr.c_str());
    // 密钥扩展
    word w[4 * (Nr + 1)];
    KeyExpansion(key, w);

    bitset<128> data;
    byte plain[16];
    ifstream in;
    ofstream out;
    in.open(R"(E:\Retained_Data\CyberSecurity\CyberSecurityVS\AES0\ex.mp3)", ios::binary);
    out.open(R"(E:\Retained_Data\CyberSecurity\CyberSecurityVS\AES0\gb.txt)", ios::binary);
    while (in.read((char*)&data, sizeof(data))) {
        divideToByte(plain, data);
        encrypt(plain, w);
        data = mergeByte(plain);
        out.write((char*)&data, sizeof(data));
        data.reset();  // 置0
    }
    in.close();
    out.close();
    out.open(R"(E:\Retained_Data\CyberSecurity\CyberSecurityVS\AES0\out.mp3)", ios::binary);
    in.open(R"(E:\Retained_Data\CyberSecurity\CyberSecurityVS\AES0\gb.txt)", ios::binary);
    while (in.read((char*)&data, sizeof(data))) {
        divideToByte(plain, data);
        decrypt(plain, w);
        data = mergeByte(plain);
        out.write((char*)&data, sizeof(data));
        data.reset();  // 置0
    }
    in.close();
    out.close();
    cout << "Running time: " << clock() - t << "ms" << endl;
    return 0;
}

标签:AES,加密,temp,arr,int,加解密,mtx,实验,byte
From: https://blog.csdn.net/weixin_44340944/article/details/140452325

相关文章

  • 实验的分流验证
    父实验下有:子实验1:手机品牌=华为,子实验2:手机品牌!=华为。一、验证只走父实验,默认进对照组,不进实验组。1.设置父实验的流量为100%2.在终端执行curlcurl--location'(sdk地址)/service/2/abtest_config/'\--header'Content-Type:application/json'\--header'Cookie:in......
  • 基于java+springboot+vue实现的实验室管理系统(文末源码+Lw)127
    基于SpringBoot+Vue的实现的实验室管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)系统功能:实验室管理系统管理员功能有个人中心,学生管理,教师管理,公告信息管理,知识库管理,实验课程管理,实验室信息管理,实验室预约管理,实验设备管理,采购记录管理,维修记录管理......
  • 基于java+springboot+vue实现的中药实验管理系统(文末源码+Lw)124
    基于SpringBoot+Vue的实现的中药实验管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+开题报告+演示视频+软件包)系统功能:本中药实验管理系统有管理员,教师,学生,实验员。管理员功能有个人中心,学生管理,教师管理,实验员管理,实验教学管理,在线学习管理,实验信息管理,实验预约管理,实......
  • 基于java+springboot+vue实现的实验室管理系统(文末源码+Lw)127
     基于SpringBoot+Vue的实现的实验室管理系统(源码+数据库+万字Lun文+流程图+ER图+结构图+演示视频+软件包)系统功能:实验室管理系统管理员功能有个人中心,学生管理,教师管理,公告信息管理,知识库管理,实验课程管理,实验室信息管理,实验室预约管理,实验设备管理,采购记录管理,维修记录......
  • x264、x265、libaom 编码对比实验
    介绍x264是一个开源的高性能H.264/MPEG-4AVC编码器,它以其优秀的压缩比和广泛的适用性而闻名。x265是一种用于将视频流编码成H.265/MPEG-HHEVC压缩格式的免费软件库和应用程序,以其下一代压缩能力和卓越的质量而闻名。作为x264的继任者,x265支持HEVC的Main、......
  • C语言——实验课大作业(十个C语言实验)
    第1关:实验8数学函数任务描述本关任务:编写一个能计算数的正弦、余弦、平方根的小程序。相关知识为了完成本关任务,你需要掌握:调用C语言自带的函数库的方法。导入函数相关库#include<math.h>导入相关库后,可以直接调用相关的函数进行运算,比如计算数a的平方根,可以通过调用s......
  • python--实验12 文件
    目录知识点第一部分:文件概述第二部分:文件的基本操作第三部分:目录管理第四部分:CSV文件读写第五部分:openpyxl等模块小结实验知识点第一部分:文件概述文件标识:找到计算机中唯一确定的文件。组成包括文件路径、文件名主干和文件扩展名。文件类型:区分了文本文件和二进......
  • [Linux+git+Gitee+Jenkins]持续集成实验安装配置详细
    首先理解持续集成原理,看懂并理解图1。图1持续集成原理结构图1中,版本控制服务器指远程代码仓库,本实验使用GitEE作为远程代码仓库;Jenkins自动化部署服务器为虚拟机,操作系统为Linux;服务器1…n为应用服务器,可使用自己物理机作为应用服务器。详......
  • 【App渗透】BurpSuite插件-Brida 2024最新自动加解密Custom plugins演示
    文章目录前言一、测试app的客户端和服务端二、BurpSuite设置代理三、反编译apk文件四、编写brida/fridahook脚本五、Customplugins自动加解密六、本期送书《二进制安全基础》如何领书总结前言之前有写过如何安装brida的文章和视频讲解,大家感兴趣的可以看看之前......
  • Host碰撞实验
    目录Host碰撞原理Host碰撞判断技巧Host碰撞检测方法Host碰撞实验步骤从攻击者的视角来进行资产的梳理,采用全端口扫描+子域名收集的方式,识别所有的企业资产暴露面。但即使是这样,往往会因为配置错误或是未及时回收等原因,依然存在着一些隐形资产Host碰撞原理当数据包的ho......