AES详细加解密步骤以及AES-128的C++实现
文章目录
- 用到的矩阵
- 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++实现相关推荐
- 【AES图像加解密】基于AES图像加解密算法的MATLAB仿真
1.软件版本 matlab2013b 2.本算法理论知识 算法的基本流程如下所示: SubBytes S-Box ShiftRows Mix Columns AddRoundKey 3.核心代码 fu ...
- php aes 256 加解密,PHP完整的AES加解密算法使用及例子(256位)
依赖PHP自身的mcrypt扩展 class aes { // CRYPTO_CIPHER_BLOCK_SIZE 32 private $_secret_key = 'default_secret_k ...
- java 和 c# 下的RSA证书+AES+DES加解密实现
java 和 c# 下的RSA+AES+DES加解密实现 前言 在实际应用中,经常有需要使用加解密的情况,RSA\AES\DES是比较常用的几种加解密方式,使用和实现方式都比较成熟可靠,本文简要介绍一 ...
- AES方式加解密的简单介绍
上面一篇文章介绍了使用DES方式进行加解密( DES方式加解密的简单介绍),我们说了DES由于使用8个字节(64bit)密钥进行加解密,所以安全性不够(当然这里的不够都是相对的),所以现在使用了密钥更 ...
- STM32F1做RSA,AES数据加解密,MD5信息摘要处理
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/qq_31878855/article/ ...
- RSA,AES算法加解密
密码的前世今生 密码Cryptology,是一种混淆人们视听的一种技术.将可以被正常认知的信息转变成不可以被识别的信息.有交流就有信息,有信息的传递,自然会产生秘密,这是文明发展的必然.密码的出生自然 ...
- java C# objective-c AES对称加解密
1 /** 2 * AES加解密 3 */ 4 public class AESHelper { 5 final static String AES_KEY = "43hr8fhu34b58 ...
- AES实现加解密-Java
一.加解密算法生态圈 目前的数据加密技术根据加密密钥类型可分私钥加密(对称加密)系统和公钥加密(非对称加密)系统.对称加密算法是较传统的加密体制,通信双方在加/解密过程中使用他们共享的单一密钥,鉴于其 ...
- java aes ebc_Delphi XE2+标准AES加解密算法(AES/EBC,CBC/PKCS5Padding-base64)
[实例简介] 实现了AES/ECB/PKCS5Padding.AES/CBC/PKCS5Padding 密钥长度128/192/256bit,密钥0填充.是标准的AES算法,支持在线AES加解密网站互 ...
最新文章
- IOS Table中Cell的重用reuse机制分析
- c语言中结构体类型只有,C语言中main()函数不要返回结构体类型(求助)
- 复习:线性表——顺序表
- 一文带你全面了解java对象的序列化和反序列化
- 结构体赋值 -- 构造函数
- 关于ITIL4 认证你必须了解的知识
- 微信下载录音文件(音轨分离 ffmpeg视频合成)
- 萤石云监控地址视频播放
- 45 个 Git 经典操作场景---教你如何合并代码
- 花花公子 243线SLOT
- ibm服务器开机显示如何设置,IBM服务器开机进入WEBBIOS界面配置RAID
- javascript接口鸭式辨型法实现
- CENTOS上的时间/时区设定
- c# OpenCvSharp 判断图片的是否黑白
- 为什么现在开发这么累呢?
- 2022-2028全球与中国夹层升降机市场现状及未来发展趋势
- linux服务器双网卡链路聚合,服务器多网卡绑定与交换机链路聚合对接探讨
- android 开源_8个开源Android教育应用
- 北大保安“高考第一人”,现在成了一校之长!网友:真·知识改变命运
- Mac 电脑四大类生产力软件,你还缺少哪些?