文章目录

    • 用到的矩阵
      • S盒
      • S盒的逆
      • 轮常量矩阵
      • 列混合矩阵
      • 列混合矩阵的逆
  • 加密步骤
    • 对密钥的处理(密钥扩展)
    • 对明文的处理
      • 字节替换
      • 行移位
        • GF(2^8^)上的乘法
      • 列混合
      • 轮密钥加
  • 解密步骤
  • 代码实现
    • 源代码
    • 运行结果
      • 加密
      • 解密

本文详细阐述了AES-128的基本加解密步骤,AES-192与AES-256加解密方式与AES-128一样,只是AES-128运算10轮,AES-192与AES-256分别运算12轮和14轮。

文中用到的示例:

明文:32 43 F6 A8 88 5A 30 8D 31 31 98 A2 E0 37 07 34
密钥:2B 7E 15 16 28 AE D2 A6 AB F7 15 88 09 CF 4F 3C
密文:39 25 84 1D 02 DC 09 FB DC 11 85 97 19 6A 0B 32

用到的矩阵

S盒

/****    0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f *//*0*/{ "63", "7C", "77", "7B", "F2", "6B", "6F", "C5", "30", "01", "67", "2B", "FE", "D7", "AB", "76" },/*1*/{ "CA", "82", "C9", "7D", "FA", "59", "47", "F0", "AD", "D4", "A2", "AF", "9C", "A4", "72", "C0" },/*2*/{ "B7", "FD", "93", "26", "36", "3F", "F7", "CC", "34", "A5", "E5", "F1", "71", "D8", "31", "15" },/*3*/{ "04", "C7", "23", "C3", "18", "96", "05", "9A", "07", "12", "80", "E2", "EB", "27", "B2", "75" },/*4*/{ "09", "83", "2C", "1A", "1B", "6E", "5A", "A0", "52", "3B", "D6", "B3", "29", "E3", "2F", "84" },/*5*/{ "53", "D1", "00", "ED", "20", "FC", "B1", "5B", "6A", "CB", "BE", "39", "4A", "4C", "58", "CF" },/*6*/{ "D0", "EF", "AA", "FB", "43", "4D", "33", "85", "45", "F9", "02", "7F", "50", "3C", "9F", "A8" },/*7*/{ "51", "A3", "40", "8F", "92", "9D", "38", "F5", "BC", "B6", "DA", "21", "10", "FF", "F3", "D2" },/*8*/{ "CD", "0C", "13", "EC", "5F", "97", "44", "17", "C4", "A7", "7E", "3D", "64", "5D", "19", "73" },/*9*/{ "60", "81", "4F", "DC", "22", "2A", "90", "88", "46", "EE", "B8", "14", "DE", "5E", "0B", "DB" },/*a*/{ "E0", "32", "3A", "0A", "49", "06", "24", "5C", "C2", "D3", "AC", "62", "91", "95", "E4", "79" },/*b*/{ "E7", "C8", "37", "6D", "8D", "D5", "4E", "A9", "6C", "56", "F4", "EA", "65", "7A", "AE", "08" },/*c*/{ "BA", "78", "25", "2E", "1C", "A6", "B4", "C6", "E8", "DD", "74", "1F", "4B", "BD", "8B", "8A" },/*d*/{ "70", "3E", "B5", "66", "48", "03", "F6", "0E", "61", "35", "57", "B9", "86", "C1", "1D", "9E" },/*e*/{ "E1", "F8", "98", "11", "69", "D9", "8E", "94", "9B", "1E", "87", "E9", "CE", "55", "28", "DF" },/*f*/{ "8C", "A1", "89", "0D", "BF", "E6", "42", "68", "41", "99", "2D", "0F", "B0", "54", "BB", "16" }

S盒的逆

/****   0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f *//*0*/{"52", "09", "6A", "D5", "30", "36", "A5", "38", "BF", "40", "A3", "9E", "81", "F3", "D7", "FB"},/*1*/{"7C", "E3", "39", "82", "9B", "2F", "FF", "87", "34", "8E", "43", "44", "C4", "DE", "E9", "CB"},/*2*/{"54", "7B", "94", "32", "A6", "C2", "23", "3D", "EE", "4C", "95", "0B", "42", "FA", "C3", "4E"},/*3*/{"08", "2E", "A1", "66", "28", "D9", "24", "B2", "76", "5B", "A2", "49", "6D", "8B", "D1", "25"},/*4*/{"72", "F8", "F6", "64", "86", "68", "98", "16", "D4", "A4", "5C", "CC", "5D", "65", "B6", "92"},/*5*/{"6C", "70", "48", "50", "FD", "ED", "B9", "DA", "5E", "15", "46", "57", "A7", "8D", "9D", "84"},/*6*/{"90", "D8", "AB", "00", "8C", "BC", "D3", "0A", "F7", "E4", "58", "05", "B8", "B3", "45", "06"},/*7*/{"D0", "2C", "1E", "8F", "CA", "3F", "0F", "02", "C1", "AF", "BD", "03", "01", "13", "8A", "6B"},/*8*/{"3A", "91", "11", "41", "4F", "67", "DC", "EA", "97", "F2", "CF", "CE", "F0", "B4", "E6", "73"},/*9*/{"96", "AC", "74", "22", "E7", "AD", "35", "85", "E2", "F9", "37", "E8", "1C", "75", "DF", "6E"},/*a*/{"47", "F1", "1A", "71", "1D", "29", "C5", "89", "6F", "B7", "62", "0E", "AA", "18", "BE", "1B"},/*b*/{"FC", "56", "3E", "4B", "C6", "D2", "79", "20", "9A", "DB", "C0", "FE", "78", "CD", "5A", "F4"},/*c*/{"1F", "DD", "A8", "33", "88", "07", "C7", "31", "B1", "12", "10", "59", "27", "80", "EC", "5F"},/*d*/{"60", "51", "7F", "A9", "19", "B5", "4A", "0D", "2D", "E5", "7A", "9F", "93", "C9", "9C", "EF"},/*e*/{"A0", "E0", "3B", "4D", "AE", "2A", "F5", "B0", "C8", "EB", "BB", "3C", "83", "53", "99", "61"},/*f*/{"17", "2B", "04", "7E", "BA", "77", "D6", "26", "E1", "69", "14", "63", "55", "21", "0C", "7D"}

轮常量矩阵

 {"01", "00", "00", "00"},{"02", "00", "00", "00"},{"04", "00", "00", "00"},{"08", "00", "00", "00"},{"10", "00", "00", "00"},{"20", "00", "00", "00"},{"40", "00", "00", "00"},{"80", "00", "00", "00"},{"1B", "00", "00", "00"},{"36", "00", "00", "00"}

列混合矩阵

列混合矩阵的逆

加密步骤

对密钥的处理(密钥扩展)

将密钥K按列优先读取到一个4×4的矩阵中,然后按列分组,将前四列分别命名为k[0] - k[3],然后向后扩展k[4]、k[5]直至k[43],接下来就是计算扩展密钥:当k[i]的i不是4的倍数的时候,k[i] = k[i - 1]⨁k[i - 1],如果i是4的倍数,则需要先将k[i - 1]列进行一轮字循环,然后进行字节替代,得到的结果与k[i - 1]和轮常量矩阵相应轮数的那一列进行抑或,得到的结果就是k[i],如此反复,得到一个4×44的扩展秘钥矩阵,然后按照4×4一组,划分为K0 - K10共11个矩阵,加密解密均用此矩阵。
例如:前文所述的密钥读到矩阵(K0)之中为:

k[0] k[1] k[2] k[3]
2B 28 AB 09
7E AE F7 CF
15 D2 15 4F
16 A6 88 3C

i为4的倍数以k[4]为例:
由于4是4的倍数,因此计算较麻烦,k[i-1]是k[3]为{09,CF,4F,3C},左移一位,结果为{CF,4F,3C,09}1◯\textcircled{1}1◯,然后根据S盒进行变换得到{8A,84,EB,01}2◯\textcircled{2}2◯,最后取轮常量矩阵的第i%4=1列{01,00,00,00}3◯\textcircled{3}3◯,将1◯\textcircled{1}1◯2◯\textcircled{2}2◯3◯\textcircled{3}3◯抑或得到k[4] = {A0,FA,FE,17}。k[8]、k[12]等等k[4i]同理

i不是4的倍数以k[5]为例:
完整的密钥矩阵为:由于5不是4的倍数,因此直接计算k[i-1]+◯\textcircled{+}+◯​k[i-4],即{A0,FA,FE,17}+◯\textcircled{+}+◯​{28,AE,D2,A6} = {88,54,2C,B1},其他的同理。

最终得到的扩展密钥矩阵如下:

k[0] k[1] k[2] k[3] k[4] k[5] k[6] k[7] k[8] k[9] k[10] k[11] k[12] k[13] k[14] k[15] k[16] k[17] k[18] k[19] k[20] k[21] k[22] k[23] k[24] k[25] k[26] k[27] k[28] k[29] k[30] k[31] k[32] k[33] k[34] k[35] k[36] k[37] k[38] k[39] k[40] k[41] k[42] k[43]
2B 28 AB 09 A0 88 23 2A F2 7A 59 73 3D 47 1E 6D EF A8 B6 DB D4 7C CA 11 6D 11 DB CA 4E 5F 84 4E EA B5 31 7F AC 19 28 57 D0 C9 E1 B6
7E AE F7 CF FA 54 A3 6C C2 96 35 59 80 16 23 7A 44 52 71 0B D1 83 F2 F9 88 0B F9 00 54 5F A6 A6 D2 8D 2B 8D 77 FA D1 5C 14 EE 3F 63
15 D2 15 4F FE 2C 39 76 95 B9 80 F6 47 FE 7E 88 A5 5B 25 AD C6 9D B8 15 A3 3E 86 93 F7 C9 4F DC 73 BA F5 29 66 DC 29 00 F9 25 0C 0C
16 A6 88 3C 17 B1 39 05 F2 43 7A 7F 7D 3E 44 3B 41 7F 3B 00 F8 87 BC BC 7A FD 41 FD 0E F3 B2 4F 21 D2 60 2F F3 21 41 6E A8 89 C8 A6

其中K0为k[0]-k[3],K1为k[4]-k[7],以此类推

对明文的处理

首先将明文按列优先保存至4×4的矩阵P中,然后进行初始变换,然后进行9轮循环运算,最后进行一轮最终轮运算之后得到密文。
初始变换:将明文矩阵与K0整体进行抑或(解密过程为与K10抑或)

例如:将明文读入到矩阵中:

32 88 31 E0
43 5A 31 37
F6 30 98 07
A8 8D A2 34

初始变换的结果为P+◯\textcircled{+}+◯​K0

19 A0 9A E9
3D F4 C6 F8
E3 E2 8D 48
BE 2B 2A 08

9轮循环运算:加密过程中为:按顺序进行字节代换、行移位、列混合以及轮密钥加
解密过程中为:按顺序进行列混合、行移位、字节替换以及轮密钥加
最终轮运算:加密过程中为:按顺序进行字节代换、行移位以及轮密钥加
解密过程中为:按顺序进行行移位,字节代换以及轮密钥加

字节替换

对输入矩阵的每一字中的两位,第一位作为行号,第二位作为列号,到S盒(加密用S盒,解密用S盒的逆)中寻找相应的字并替换成新的。
例如:在加密的第一轮过程中,输入的矩阵第一个字为“19”,到S盒中寻找行号为1,列号为9的的字为D4,因此将19替换为D4,第一轮替换的结果为:

行移位

加密过程中,将第输入矩阵的第2,3,4行分别左移1,2,3位,解密过程中改为右移。
例如:加密第一轮过程中行移位之后的结果为:

GF(28)上的乘法

A = a0a1a2a3a4a5a6a7a8
01×A = A
02×A:若a0=0,直接左移一位,右侧补0,即 =a1a2a3a4a5a6a7a80
若a0≠0,则左移一位右侧补0后与1B(00011011)抑或
其他乘法可由以上两式推导出来,譬如03(00000011)×A即为(01(00000001) +◯\textcircled{+}+◯​ 02(00000010)) ×A = (01×A) +◯\textcircled{+}+◯​ (02×A),04(00000100) = 02×02,09(00001001) = 08 +◯\textcircled{+}+◯​ 01,0B(00001011)=08 +◯\textcircled{+}+◯​ 02 +◯\textcircled{+}+◯​ 01,以此类推

列混合

将输入的矩阵左乘列混合矩阵(解密过程中为左乘列混合矩阵的逆),运算过程中乘法为GF(28)上的乘法,加法为按位异或
例如,第一轮加密过程中列混合后的矩阵为:

轮密钥加

第i轮就将输入矩阵与Ki矩阵逐字抑或(加解密一样)
例如:加密过程中第一轮,输入矩阵为:

K1为:

抑或结果为:


第二轮至第十轮的运算结果分别为:

解密步骤

将密文按列优先读进4×4矩阵,然后进行初始变换,然后进行一轮最终轮运算,最后进行9轮循环运算之后得到密文。

代码实现

源代码

/******************************************************************************************* Name: AES.cpp* Author: kongtaoxing* Time: 2022/10/08* Tips: All algebraic operations in this project are performed in the GF(2^8) finite field******************************************************************************************/#include<string>
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;char Sbox[16][16][3] = {/****    0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f *//*0*/{ "63", "7C", "77", "7B", "F2", "6B", "6F", "C5", "30", "01", "67", "2B", "FE", "D7", "AB", "76" },/*1*/{ "CA", "82", "C9", "7D", "FA", "59", "47", "F0", "AD", "D4", "A2", "AF", "9C", "A4", "72", "C0" },/*2*/{ "B7", "FD", "93", "26", "36", "3F", "F7", "CC", "34", "A5", "E5", "F1", "71", "D8", "31", "15" },/*3*/{ "04", "C7", "23", "C3", "18", "96", "05", "9A", "07", "12", "80", "E2", "EB", "27", "B2", "75" },/*4*/{ "09", "83", "2C", "1A", "1B", "6E", "5A", "A0", "52", "3B", "D6", "B3", "29", "E3", "2F", "84" },/*5*/{ "53", "D1", "00", "ED", "20", "FC", "B1", "5B", "6A", "CB", "BE", "39", "4A", "4C", "58", "CF" },/*6*/{ "D0", "EF", "AA", "FB", "43", "4D", "33", "85", "45", "F9", "02", "7F", "50", "3C", "9F", "A8" },/*7*/{ "51", "A3", "40", "8F", "92", "9D", "38", "F5", "BC", "B6", "DA", "21", "10", "FF", "F3", "D2" },/*8*/{ "CD", "0C", "13", "EC", "5F", "97", "44", "17", "C4", "A7", "7E", "3D", "64", "5D", "19", "73" },/*9*/{ "60", "81", "4F", "DC", "22", "2A", "90", "88", "46", "EE", "B8", "14", "DE", "5E", "0B", "DB" },/*a*/{ "E0", "32", "3A", "0A", "49", "06", "24", "5C", "C2", "D3", "AC", "62", "91", "95", "E4", "79" },/*b*/{ "E7", "C8", "37", "6D", "8D", "D5", "4E", "A9", "6C", "56", "F4", "EA", "65", "7A", "AE", "08" },/*c*/{ "BA", "78", "25", "2E", "1C", "A6", "B4", "C6", "E8", "DD", "74", "1F", "4B", "BD", "8B", "8A" },/*d*/{ "70", "3E", "B5", "66", "48", "03", "F6", "0E", "61", "35", "57", "B9", "86", "C1", "1D", "9E" },/*e*/{ "E1", "F8", "98", "11", "69", "D9", "8E", "94", "9B", "1E", "87", "E9", "CE", "55", "28", "DF" },/*f*/{ "8C", "A1", "89", "0D", "BF", "E6", "42", "68", "41", "99", "2D", "0F", "B0", "54", "BB", "16" }};// S盒char Sboxni[16][16][3] = {/****   0     1     2     3     4     5     6     7     8     9     a     b     c     d     e     f *//*0*/{"52", "09", "6A", "D5", "30", "36", "A5", "38", "BF", "40", "A3", "9E", "81", "F3", "D7", "FB"},/*1*/{"7C", "E3", "39", "82", "9B", "2F", "FF", "87", "34", "8E", "43", "44", "C4", "DE", "E9", "CB"},/*2*/{"54", "7B", "94", "32", "A6", "C2", "23", "3D", "EE", "4C", "95", "0B", "42", "FA", "C3", "4E"},/*3*/{"08", "2E", "A1", "66", "28", "D9", "24", "B2", "76", "5B", "A2", "49", "6D", "8B", "D1", "25"},/*4*/{"72", "F8", "F6", "64", "86", "68", "98", "16", "D4", "A4", "5C", "CC", "5D", "65", "B6", "92"},/*5*/{"6C", "70", "48", "50", "FD", "ED", "B9", "DA", "5E", "15", "46", "57", "A7", "8D", "9D", "84"},/*6*/{"90", "D8", "AB", "00", "8C", "BC", "D3", "0A", "F7", "E4", "58", "05", "B8", "B3", "45", "06"},/*7*/{"D0", "2C", "1E", "8F", "CA", "3F", "0F", "02", "C1", "AF", "BD", "03", "01", "13", "8A", "6B"},/*8*/{"3A", "91", "11", "41", "4F", "67", "DC", "EA", "97", "F2", "CF", "CE", "F0", "B4", "E6", "73"},/*9*/{"96", "AC", "74", "22", "E7", "AD", "35", "85", "E2", "F9", "37", "E8", "1C", "75", "DF", "6E"},/*a*/{"47", "F1", "1A", "71", "1D", "29", "C5", "89", "6F", "B7", "62", "0E", "AA", "18", "BE", "1B"},/*b*/{"FC", "56", "3E", "4B", "C6", "D2", "79", "20", "9A", "DB", "C0", "FE", "78", "CD", "5A", "F4"},/*c*/{"1F", "DD", "A8", "33", "88", "07", "C7", "31", "B1", "12", "10", "59", "27", "80", "EC", "5F"},/*d*/{"60", "51", "7F", "A9", "19", "B5", "4A", "0D", "2D", "E5", "7A", "9F", "93", "C9", "9C", "EF"},/*e*/{"A0", "E0", "3B", "4D", "AE", "2A", "F5", "B0", "C8", "EB", "BB", "3C", "83", "53", "99", "61"},/*f*/{"17", "2B", "04", "7E", "BA", "77", "D6", "26", "E1", "69", "14", "63", "55", "21", "0C", "7D"}};    // S盒的逆char Rcon[10][4][3] = {{"01", "00", "00", "00"},{"02", "00", "00", "00"},{"04", "00", "00", "00"},{"08", "00", "00", "00"},{"10", "00", "00", "00"},{"20", "00", "00", "00"},{"40", "00", "00", "00"},{"80", "00", "00", "00"},{"1B", "00", "00", "00"},{"36", "00", "00", "00"}
};  // 轮常量矩阵static int flag_e = 00; //加密循环轮数
static int flag_d = 10; //解密循环轮数vector<string> MixC = {"02", "01", "01", "03"};
vector<string> MixCni = {"0E", "09", "0D", "0B"};string encrypt(string p, string k);
string decrypt(string c, string k);
string LowToUpper(string low);  //小写字母转大写字母
string HextoBin(string Hex);  //十六进制转二进制
string BintoHex(string Bin);  //二进制转十六进制
int HexToDec(char Hex);   //十六进制字符转10进制数字
vector<vector<string>> nineRounds(vector<vector<string>> P, vector<vector<string>> K, char ed);   //9轮变换
vector<vector<string>> finalRounds(vector<vector<string>> P, vector<vector<string>> K, char ed);   //最终轮变换
vector<vector<string>> subBytes(vector<vector<string>> P, char ed); // 字节代换
vector<vector<string>> ShiftRows(vector<vector<string>> P);   // 行移位
vector<vector<string>> invShiftRows(vector<vector<string>> P);   // 逆行移位
vector<vector<string>> MixColumns(vector<vector<string>> p, vector<string> MisC);   //列混合
vector<vector<string>> AddRoundKey(vector<vector<string>> P, vector<vector<string>> K, char ed);  //轮密钥加
vector<vector<string>> subKey(vector<vector<string>> k);  //密钥扩展
string hexXor(string a, string b); //16进制抑或
string hexTimes(string a, string b);  //16进制乘法,a为列混合矩阵元素,只取01,02,03
vector<vector<string>> transMatrix(vector<vector<string>> K);   // 转置矩阵string encrypt(string p, string k) {vector<vector<string>> P(4, vector<string>(4, "00"));vector<vector<string>> Key(44, vector<string>(4, "00"));string ans = "";for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {for(int kk = 0; kk < 2; kk++) {P[i][j][kk] = p[(i * 4 + j) * 3 + kk];   //丢弃掉中间的空格,将字符串转换为矩阵}}}for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {for(int kk = 0; kk < 2; kk++) {Key[i][j][kk] = k[(i * 4 + j) * 3 + kk];   //丢弃掉中间的空格,将字符串转换为矩阵}}}Key = subKey(Key);for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {P[i][j] = hexXor(P[i][j], Key[i][j]);   //初始变换(Initial round)}}P = transMatrix(P);   // 明文矩阵是竖着读进去的,但是需要横着用P = nineRounds(P, Key, 'e');   //9轮循环运算P = finalRounds(P, Key, 'e');  //最终轮运算P = transMatrix(P);  //还原回去for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {ans += P[i][j];ans += " ";}}return ans;    // 得到密文
}string decrypt(string c, string k) {vector<vector<string>> C(4, vector<string>(4, "00"));vector<vector<string>> Key(44, vector<string>(4, "00"));string ans = "";for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {for(int kk = 0; kk < 2; kk++) {C[i][j][kk] = c[(i * 4 + j) * 3 + kk];   //丢弃掉中间的空格,将字符串转换为矩阵}}}for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {for(int kk = 0; kk < 2; kk++) {Key[i][j][kk] = k[(i * 4 + j) * 3 + kk];   //丢弃掉中间的空格,将字符串转换为矩阵}}}Key = subKey(Key);for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {C[i][j] = hexXor(C[i][j], Key[40 + i][j]);   //逆初始变换(Initial round)}}C = transMatrix(C);   // 密文矩阵是竖着读进去的,但是需要横着用C = finalRounds(C, Key, 'd');  //最终轮运算C = nineRounds(C, Key, 'd');   //9轮循环运算C = transMatrix(C); //还原回去for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {ans += C[i][j];ans += " ";}}return ans;    // 得到密文
}vector<vector<string>> subKey(vector<vector<string>> K) {  //密钥扩展vector<vector<string>> sKey(44, vector<string>(4, "00"));for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {sKey[i][j] = K[i][j];}}for (int i = 4; i < 44; i++) {if (i % 4 != 0) {for (int j = 0; j < 4; j++) {sKey[i][j] = hexXor(sKey[i - 4][j], sKey[i - 1][j]);}}else {vector<string> tempK = sKey[i - 1];  //字循环string temp = tempK[0];for (int j = 0; j < 3; j++) {tempK[j] = tempK[j + 1];}tempK[3] = temp;vector<string> SK = tempK;           //S盒for (int j = 0; j < 4; j++) {SK[j] = Sbox[HexToDec(tempK[j][0])][HexToDec(tempK[j][1])];sKey[i][j] = hexXor(hexXor(sKey[i - 4][j], SK[j]), Rcon[i / 4 - 1][j]);}}}return sKey;
}vector<vector<string>> subBytes(vector<vector<string>> P, char ed) { // 字节代换vector<vector<string>> SP(4, vector<string>(4, "00"));if (ed == 'e') {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {SP[i][j] = Sbox[HexToDec(P[i][j][0])][HexToDec(P[i][j][1])];  //字节代换(SubBytes)}}}else {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {SP[i][j] = Sboxni[HexToDec(P[i][j][0])][HexToDec(P[i][j][1])];  //字节代换(SubBytes)}}}return SP;
}vector<vector<string>> ShiftRows(vector<vector<string>> P) {  // 行移位(ShiftRows)for (int i = 1; i < 4; i++) {vector<string> temp;for (int j = 0; j < i; j++) {temp.push_back(P[i][j]);}for (int j = i; j < 4; j++) {P[i][j - i] = P[i][j];}for (int j = 4 - i; j < 4; j++) {P[i][j] = temp[j - (4 - i)];}}return P;
}vector<vector<string>> invShiftRows(vector<vector<string>> P) {   // 逆行移位for (int i = 1; i < 4; i++) {vector<string> temp;for (int j = 4 - i; j < 4; j++) {temp.push_back(P[i][j]);}for (int j = 3; j >= i; j--) {P[i][j] = P[i][j - i];}for (int j = 0; j < i; j++) {P[i][j] = temp[j];}}return P;
}vector<vector<string>> MixColumns(vector<vector<string>> p, vector<string> A) {   //列混合p = transMatrix(p);  //将列转化为行,方便计算vector<vector<string>> SP(4, vector<string>(4, "00"));  for (int i = 0; i < 4; i++) {  // GF(2^8)上的矩阵乘法SP[i][0] = hexXor(hexXor(hexTimes(A[0], p[i][0]), hexTimes(A[3], p[i][1])), hexXor(hexTimes(A[2], p[i][2]), hexTimes(A[1], p[i][3])));SP[i][1] = hexXor(hexXor(hexTimes(A[1], p[i][0]), hexTimes(A[0], p[i][1])), hexXor(hexTimes(A[3], p[i][2]), hexTimes(A[2], p[i][3])));SP[i][2] = hexXor(hexXor(hexTimes(A[2], p[i][0]), hexTimes(A[1], p[i][1])), hexXor(hexTimes(A[0], p[i][2]), hexTimes(A[3], p[i][3])));SP[i][3] = hexXor(hexXor(hexTimes(A[3], p[i][0]), hexTimes(A[2], p[i][1])), hexXor(hexTimes(A[1], p[i][2]), hexTimes(A[0], p[i][3])));}SP = transMatrix(SP);  //再转化回去return SP;
}vector<vector<string>> AddRoundKey(vector<vector<string>> P, vector<vector<string>> K, char ed) {  //轮密钥加P = transMatrix(P);   //轮密钥加要用列,先翻转一下vector<vector<string>> ARK(4, vector<string>(4, "00"));if (ed == 'e') {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {ARK[i][j] = hexXor(P[i][j], K[flag_e * 4 + i][j]);}}}else {for (int i = 0; i < 4; i++) {for (int j = 0; j < 4; j++) {ARK[i][j] = hexXor(P[i][j], K[flag_d * 4 + i][j]);}}}ARK = transMatrix(ARK);   //再给他翻转回去return ARK;
}vector<vector<string>> nineRounds(vector<vector<string>> P, vector<vector<string>> K, char ed) {  // 9轮变换if (ed == 'e') {for (int i = 0; i < 9; i++) {flag_e++;P = subBytes(P, 'e');P = ShiftRows(P);P = MixColumns(P, MixC);P = AddRoundKey(P, K, 'e');}}else {for (int i = 0; i < 9; i++) {flag_d--;P = MixColumns(P, MixCni);P = invShiftRows(P);P = subBytes(P, 'd');P = AddRoundKey(P, K, 'd');}}return P;
}vector<vector<string>> finalRounds(vector<vector<string>> P, vector<vector<string>> K, char ed) {   //最终轮变换if (ed == 'e') {flag_e++;P = subBytes(P, 'e');P = ShiftRows(P);P = AddRoundKey(P, K, 'e');}else {flag_d--;P = invShiftRows(P);P = subBytes(P, 'd');P = AddRoundKey(P, K, 'd');}return P;
}string HextoBin(string Hex) {string Bin = "";for(int i = 0; i < Hex.length(); i++) {if(Hex[i] == '0') Bin += "0000";else if(Hex[i] == '1') Bin += "0001";else if(Hex[i] == '2') Bin += "0010";else if(Hex[i] == '3') Bin += "0011";else if(Hex[i] == '4') Bin += "0100";else if(Hex[i] == '5') Bin += "0101";else if(Hex[i] == '6') Bin += "0110";else if(Hex[i] == '7') Bin += "0111";else if(Hex[i] == '8') Bin += "1000";else if(Hex[i] == '9') Bin += "1001";else if(Hex[i] == 'A') Bin += "1010";else if(Hex[i] == 'B') Bin += "1011";else if(Hex[i] == 'C') Bin += "1100";else if(Hex[i] == 'D') Bin += "1101";else if(Hex[i] == 'E') Bin += "1110";else Bin += "1111";}return Bin;
}string BintoHex(string Bin) {string Hex = "";for(int i = 0; i < Bin.length() / 4; i++) {int num = (Bin[4 * i] - '0') * 8 + (Bin[4 * i + 1] - '0') * 4 + (Bin[4 * i + 2] - '0') * 2 + (Bin[4 * i + 3] - '0');if(0 <= num && num <= 9) Hex += (num + '0');else if(num == 10) Hex += "A";else if(num == 11) Hex += "B";else if(num == 12) Hex += "C";else if(num == 13) Hex += "D";else if(num == 14) Hex += "E";else Hex += "F";}return Hex;
}string LowToUpper(string low) {for(int i = 0; i < low.length(); i++) {if(low[i] >= 'a' && low[i] <= 'z') {low[i] -= 32;}}return low;
}int HexToDec(char Hex) {if(Hex >= '0' && Hex <= '9')return Hex - '0';else return Hex - 55;
}string hexXor(string a, string b) {string A = HextoBin(a);string B = HextoBin(b);string x(A.length(), '0');for (int i = 0; i < A.length(); i++) {x[i] = (A[i] - '0') ^ (B[i] - '0') + '0';}return BintoHex(x);
}string hexTimes(string a, string b) {string A = HextoBin(a);string B = HextoBin(b);string ans(8, '0');if (a == "01") {return b;}else if (a == "02") {for (int i = 0; i < 7; i++) {ans[i] = B[i + 1];}if (B[0] == '0') {return BintoHex(ans);}else {return hexXor(BintoHex(ans), "1B");}}else if (a == "03") {return hexXor(hexTimes("02", b), b);}else if (a == "04") {return hexTimes("02", hexTimes("02", b));}else if (a == "08") {return hexTimes("02", hexTimes("04", b));}else if (a == "09") {return hexXor(b, hexTimes("08", b));}else if (a == "0E") {return hexXor(hexTimes("08", b), hexXor(hexTimes("04", b), hexTimes("02", b)));}else if (a == "0D") {return hexXor(hexTimes("09", b), hexTimes("04", b));}else if (a == "0B") {return hexXor(hexTimes("09", b), hexTimes("02", b));}else {cout << "列混合步骤出错,用到了不支持的矩阵乘法,请检查列混合矩阵!" << endl;system("pause");return 0;}
}vector<vector<string>> transMatrix(vector<vector<string>> K) {vector<vector<string>> TK(K[0].size(), vector<string>(K.size(), "00"));for (int i =0; i < K.size(); i++) {for (int j = 0; j < K[0].size(); j++) {TK[j][i] = K[i][j];}}return TK;
}int main() {string PATH;string p, c, k;   //明文、密文、密钥cout << "-------------------AES-128加/解密工具--------------------" << endl << endl;cout << "请输入你想加密还是解密,加密为e,解密为d:";string ed;cin >> ed;cout << "\n请输入文件路径:";cin >> PATH;fstream File(PATH, ios::out|ios::in);   // 以读取和覆盖的方式打开文件if(!File.is_open()){cout << "\n打开或创建文件失败,请检查文件是否被占用!\n" << endl;system("pause");return 0;}vector<string> textBox;while(!File.eof()) {string temp;getline(File, temp, '\n');textBox.push_back(temp);}File.seekg(0, ios::beg);  // 回到文件头if (textBox.size() == 2) {   // 文件中只有明文和密钥p = textBox[0];k = textBox[1];textBox.push_back("");}else {                       // 文件中有明文、密钥和密文p = textBox[0];k = textBox[1];c = textBox[2];}k = LowToUpper(k);p = LowToUpper(p);c = LowToUpper(c);  // 将读入字符全部变为大写,增加健壮性if (ed == "e" || ed == "E") {c = encrypt(p, k);textBox[2] = c;for (int i = 0; i < textBox.size(); i++) {File << textBox[i];if (i != textBox.size() - 1) {File << endl;}}cout << "加密成功,密文已保存至源文件最后一行,请到源文件查看!" << endl;File.close();   // 及时关闭文件,防止内存泄露}else if (ed == "d" || ed == "D") {p = decrypt(c, k);textBox[0] = p;for (int i = 0; i < textBox.size(); i++) {File << textBox[i];if (i != textBox.size() - 1) {File << endl;}}cout << "解密成功,明文已保存至源文件第一行,请到源文件查看!" << endl;File.close();}else {cout << "参数错误!\n" << endl;File.close();  // Close the filesystem("pause");return 0;}system("pause");return 0;
}

运行结果

加密

加密前(第一行明文,第二行密钥,第三行密文):

加密过程:

结果:

3D 71 F7 44 18 02 79 6D 5B 55 21 66 AB 74 DF EF
A4 32 E2 2D 8B BA 53 62 D5 57 19 35 32 5A D1 32
B5 86 4C 93 73 EF D6 CB 89 E8 12 5F 33 E0 7D E6

解密

解密前:

解密中:

解密结果:

与加密对照之后发现一样,程序运行无误

AES详细加解密步骤以及AES-128的C++实现相关推荐

  1. 【AES图像加解密】基于AES图像加解密算法的MATLAB仿真

    1.软件版本 matlab2013b 2.本算法理论知识 算法的基本流程如下所示: SubBytes S-Box ShiftRows Mix Columns AddRoundKey 3.核心代码 fu ...

  2. php aes 256 加解密,PHP完整的AES加解密算法使用及例子(256位)

    依赖PHP自身的mcrypt扩展 class aes { // CRYPTO_CIPHER_BLOCK_SIZE 32 private $_secret_key = 'default_secret_k ...

  3. java 和 c# 下的RSA证书+AES+DES加解密实现

    java 和 c# 下的RSA+AES+DES加解密实现 前言 在实际应用中,经常有需要使用加解密的情况,RSA\AES\DES是比较常用的几种加解密方式,使用和实现方式都比较成熟可靠,本文简要介绍一 ...

  4. AES方式加解密的简单介绍

    上面一篇文章介绍了使用DES方式进行加解密( DES方式加解密的简单介绍),我们说了DES由于使用8个字节(64bit)密钥进行加解密,所以安全性不够(当然这里的不够都是相对的),所以现在使用了密钥更 ...

  5. STM32F1做RSA,AES数据加解密,MD5信息摘要处理

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_31878855/article/ ...

  6. RSA,AES算法加解密

    密码的前世今生 密码Cryptology,是一种混淆人们视听的一种技术.将可以被正常认知的信息转变成不可以被识别的信息.有交流就有信息,有信息的传递,自然会产生秘密,这是文明发展的必然.密码的出生自然 ...

  7. java C# objective-c AES对称加解密

    1 /** 2 * AES加解密 3 */ 4 public class AESHelper { 5 final static String AES_KEY = "43hr8fhu34b58 ...

  8. AES实现加解密-Java

    一.加解密算法生态圈 目前的数据加密技术根据加密密钥类型可分私钥加密(对称加密)系统和公钥加密(非对称加密)系统.对称加密算法是较传统的加密体制,通信双方在加/解密过程中使用他们共享的单一密钥,鉴于其 ...

  9. java aes ebc_Delphi XE2+标准AES加解密算法(AES/EBC,CBC/PKCS5Padding-base64)

    [实例简介] 实现了AES/ECB/PKCS5Padding.AES/CBC/PKCS5Padding 密钥长度128/192/256bit,密钥0填充.是标准的AES算法,支持在线AES加解密网站互 ...

最新文章

  1. IOS Table中Cell的重用reuse机制分析
  2. c语言中结构体类型只有,C语言中main()函数不要返回结构体类型(求助)
  3. 复习:线性表——顺序表
  4. 一文带你全面了解java对象的序列化和反序列化
  5. 结构体赋值 -- 构造函数
  6. 关于ITIL4 认证你必须了解的知识
  7. 微信下载录音文件(音轨分离 ffmpeg视频合成)
  8. 萤石云监控地址视频播放
  9. 45 个 Git 经典操作场景---教你如何合并代码
  10. 花花公子 243线SLOT
  11. ibm服务器开机显示如何设置,IBM服务器开机进入WEBBIOS界面配置RAID
  12. javascript接口鸭式辨型法实现
  13. CENTOS上的时间/时区设定
  14. c# OpenCvSharp 判断图片的是否黑白
  15. 为什么现在开发这么累呢?
  16. 2022-2028全球与中国夹层升降机市场现状及未来发展趋势
  17. linux服务器双网卡链路聚合,服务器多网卡绑定与交换机链路聚合对接探讨
  18. android 开源_8个开源Android教育应用
  19. 北大保安“高考第一人”,现在成了一校之长!网友:真·知识改变命运
  20. Mac 电脑四大类生产力软件,你还缺少哪些?

热门文章

  1. 用公众号给女朋友推送早安问候(恋爱值♥♥♥♥♥)
  2. 腹肌撕裂者x高清中文字幕
  3. 这些“古老”的编程语言,你还在使用吗?
  4. AntDB-M数据库锁分析,不要错过!
  5. Oracle数据库管理每周一例-第十五期 一些工具和小技巧
  6. R编程错误:变数的长度不一样
  7. python:爱因斯坦阶梯问题
  8. c语言fputc 函数头,简单对比C语言中的fputs()函数和fputc()函数
  9. Monaco Editor教程(一): 开源项目 monaco-editor 开启本地开发环境
  10. 关于Bpm系统的流程设计器