分组密码复习
分组密码复习
分组模式#
ECB#
CBC#
CFB#
OFB#
CRT#
DES#
DES(Data Encryption Standard)除了初始置换和逆初始置换外,其结构与Feistel密码结构相同。
分组长度 | 密钥长度 | 轮数 |
---|---|---|
64bit | 56bit | 16 |
整体方案:
加密#
将64bit的明文加密为64bit的密文,其中先对明文进行处理,主要分为以下三个阶段:
初始置换#
初始置换就是重排列明文分组的64bit数据:
假设明文
16轮变换#
每轮都有置换和代换运算:
注意,最后一轮不进行交换,即
将64bit的输入分为左右两半各32bit,记为
其中轮密钥
- 输入右半部分32bit的
,首先通过扩展置换(E表)扩展为48bit,即将 的16个比特重复一次,可以看出该置换 “扩展”了数据。
- 扩展后的48bit再与子密钥
异或。
- 再通过代换/选择(S盒),产生32bit的输出,其中代换是由8个S盒组成,每个S盒的输入为6bit(【行】-第1个和第6个比特;【列】-中间4比特),输出4bit。
- 最后通过一个
置换,就能产生 的32bit的输出。
逆初始置换#
在第16轮变换后的输出分为左右两半,并交换次序,再通过一个逆初始置换
密钥生成#
加密时使用的轮密钥
置换1#
56bit的初始密钥
左循环移位#
然后在第
置换2#
左循环移位后的
解密#
解密与加密使用同一种算法,但子密钥使用顺序相反,即
例子#
手推#
- 加密
- 解密
代码#
(1)简单输入输出
// C语言实现
#include<stdio.h>
#include<string.h>
/*
参考链接:https://blog.csdn.net/zidane_2014/article/details/37988657
*/
int IP_Table[64] = { //IP置换矩阵
58, 50, 42, 34, 26, 18, 10, 2, 60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6, 64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1, 59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5, 63, 55, 47, 39, 31, 23, 15, 7 };
int E_Table[48] = { //扩展矩阵
32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13, 12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29, 28, 29, 30, 31, 32, 1 };
int P_Table[32] = { // P 盒
16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10,
2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25 };
int IPR_Table[64] = { //逆IP置换矩阵
40, 8, 48, 16, 56, 24, 64, 32, 39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30, 37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28, 35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26, 33, 1, 41, 9, 49, 17, 57, 25 };
int PC1_Table[56] = { //密钥第一次置换矩阵
57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36,
63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4 };
int PC2_Table[48] = { // 密钥第二次置换矩阵
14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8, 16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55, 30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53, 46, 42, 50, 36, 29, 32 };
int S_Box[8][4][16] = { //8个S盒 三维数组
// S1
14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12, 5, 9, 0, 7,
0, 15, 7, 4, 14, 2, 13, 1, 10, 6, 12, 11, 9, 5, 3, 8,
4, 1, 14, 8, 13, 6, 2, 11, 15, 12, 9, 7, 3, 10, 5, 0,
15, 12, 8, 2, 4, 9, 1, 7, 5, 11, 3, 14, 10, 0, 6, 13,
// S2
15, 1, 8, 14, 6, 11, 3, 4, 9, 7, 2, 13, 12, 0, 5, 10,
3, 13, 4, 7, 15, 2, 8, 14, 12, 0, 1, 10, 6, 9, 11, 5,
0, 14, 7, 11, 10, 4, 13, 1, 5, 8, 12, 6, 9, 3, 2, 15,
13, 8, 10, 1, 3, 15, 4, 2, 11, 6, 7, 12, 0, 5, 14, 9,
// S3
10, 0, 9, 14, 6, 3, 15, 5, 1, 13, 12, 7, 11, 4, 2, 8,
13, 7, 0, 9, 3, 4, 6, 10, 2, 8, 5, 14, 12, 11, 15, 1,
13, 6, 4, 9, 8, 15, 3, 0, 11, 1, 2, 12, 5, 10, 14, 7,
1, 10, 13, 0, 6, 9, 8, 7, 4, 15, 14, 3, 11, 5, 2, 12,
// S4
7, 13, 14, 3, 0, 6, 9, 10, 1, 2, 8, 5, 11, 12, 4, 15,
13, 8, 11, 5, 6, 15, 0, 3, 4, 7, 2, 12, 1, 10, 14, 9,
10, 6, 9, 0, 12, 11, 7, 13, 15, 1, 3, 14, 5, 2, 8, 4,
3, 15, 0, 6, 10, 1, 13, 8, 9, 4, 5, 11, 12, 7, 2, 14,
// S5
2, 12, 4, 1, 7, 10, 11, 6, 8, 5, 3, 15, 13, 0, 14, 9,
14, 11, 2, 12, 4, 7, 13, 1, 5, 0, 15, 10, 3, 9, 8, 6,
4, 2, 1, 11, 10, 13, 7, 8, 15, 9, 12, 5, 6, 3, 0, 14,
11, 8, 12, 7, 1, 14, 2, 13, 6, 15, 0, 9, 10, 4, 5, 3,
// S6
12, 1, 10, 15, 9, 2, 6, 8, 0, 13, 3, 4, 14, 7, 5, 11,
10, 15, 4, 2, 7, 12, 9, 5, 6, 1, 13, 14, 0, 11, 3, 8,
9, 14, 15, 5, 2, 8, 12, 3, 7, 0, 4, 10, 1, 13, 11, 6,
4, 3, 2, 12, 9, 5, 15, 10, 11, 14, 1, 7, 6, 0, 8, 13,
// S7
4, 11, 2, 14, 15, 0, 8, 13, 3, 12, 9, 7, 5, 10, 6, 1,
13, 0, 11, 7, 4, 9, 1, 10, 14, 3, 5, 12, 2, 15, 8, 6,
1, 4, 11, 13, 12, 3, 7, 14, 10, 15, 6, 8, 0, 5, 9, 2,
6, 11, 13, 8, 1, 4, 10, 7, 9, 5, 0, 15, 14, 2, 3, 12,
// S8
13, 2, 8, 4, 6, 15, 11, 1, 10, 9, 3, 14, 5, 0, 12, 7,
1, 15, 13, 8, 10, 3, 7, 4, 12, 5, 6, 11, 0, 14, 9, 2,
7, 11, 4, 1, 9, 12, 14, 2, 0, 6, 10, 13, 15, 3, 5, 8,
2, 1, 14, 7, 4, 10, 8, 13, 15, 12, 9, 0, 3, 5, 6, 11
};
static void CharToBit(const char input[], int output[])//把CHAR转换为INT
{
int i, j;
for (j = 0; j < 8; j++)
{
for (i = 0; i < 8; i++)
{
output[7 * (j + 1) - i + j] = (input[j] >> i) & 1;
}
}
};
static void BitToChar(const int intput[], char output[])//把INT转换为CHAR
{
int i, j;
for (j = 0; j < 8; j++)
{
for (i = 0; i < 8; i++)
{
output[j] = output[j] * 2 + intput[i + 8 * j];
}
}
};
static void Xor(int* INA, int* INB, int len)//异或操作
{
int i;
for (i = 0; i < len; i++)
{
*(INA + i) = *(INA + i) ^ *(INB + i);
}
};
static void IP(const int input[64], int output[64], int table[64])//初始IP置换
{
int i;
for (i = 0; i < 64; i++)
{
output[i] = input[table[i] - 1];//减1操作不可少!!
}
};
static void E(const int input[32], int output[48], int table[48])//E扩展
{
int i;
for (i = 0; i < 48; i++)
{
output[i] = input[table[i] - 1];
}
};
static void P(const int input[32], int output[32], int table[32])//P置换
{
int i;
for (i = 0; i < 32; i++)
{
output[i] = input[table[i] - 1];
}
};
static void IP_In(const int input[64], int output[64], int table[64])//逆IP
{
int i;
for (i = 0; i < 64; i++)
{
output[i] = input[table[i] - 1];
}
};
static void PC_1(const int input[64], int output[56], int table[56])//PC_1
{
int i;
for (i = 0; i < 56; i++)
{
output[i] = input[table[i] - 1];
}
};
static void PC_2(const int input[56], int output[48], int table[48])//PC_2
{
int i;
for (i = 0; i < 48; i++)
{
output[i] = input[table[i] - 1];
}
};
static void S(const int input[48], int output[32], int table[8][4][16])//S盒压缩
{
int i = 0;
int j = 0;
int INT[8];
for (; i < 48; i = i + 6)
{
INT[j] = table[j][(input[i] << 1) + (input[i + 5])][(input[i + 1] << 3) + (input[i + 2] << 2) + (input[i + 3] << 1) + (input[i + 4])];
j++;
}
for (j = 0; j < 8; j++)
{
for (i = 0; i < 4; i++)
{
output[3 * (j + 1) - i + j] = (INT[j] >> i) & 1;
}
}
};
static void F_func(int input[32], int output[32], int subkey[48])//完成DES算法轮变换
{
int len = 48;
int temp[48] = { 0 };
int temp_1[32] = { 0 };
E(input, temp, E_Table);//E扩展变换(32bit -> 48bit)
Xor(temp, subkey, len);//与子密钥异或
S(temp, temp_1, S_Box);//压缩变换(S盒)(48bit -> 32bit)
P(temp_1, output, P_Table);//P置换
};
static void RotateL(const int input[28], int output[28], int leftCount)//完成子密钥扩展的循环左移
{
int i;
int len = 28;
for (i = 0; i < len; i++)
{
output[i] = input[(i + leftCount) % len];
}
};
static void subKey_fun(const int input[64], int Subkey[16][48])//完成16轮子密钥生成
{
int loop = 1, loop_2 = 2;
int i, j;
int c[28], d[28];
int pc_1[56] = { 0 };
int pc_2[16][56] = { 0 };
int rotatel_c[16][28] = { 0 };
int rotatel_d[16][28] = { 0 };
PC_1(input, pc_1, PC1_Table);
for (i = 0; i < 28; i++)
{
c[i] = pc_1[i];
d[i] = pc_1[i + 28];
}
int leftCount = 0;
for (i = 1; i < 17; i++)
{
if (i == 1 || i == 2 || i == 9 || i == 16)
{
leftCount += loop;
RotateL(c, rotatel_c[i - 1], leftCount);
RotateL(d, rotatel_d[i - 1], leftCount);
}
else
{
leftCount += loop_2;
RotateL(c, rotatel_c[i - 1], leftCount);
RotateL(d, rotatel_d[i - 1], leftCount);
}
}
for (i = 0; i < 16; i++)
{
for (j = 0; j < 28; j++)
{
pc_2[i][j] = rotatel_c[i][j];
pc_2[i][j + 28] = rotatel_d[i][j];
}
}
for (i = 0; i < 16; i++)
{
PC_2(pc_2[i], Subkey[i], PC2_Table);
}
};
//DES加密运算
static void DES_Efun(char input[8], char key_in[8], int output[64])
{
int Ip[64] = { 0 };//存储初始置换后的矩阵
int output_1[64] = { 0 }; //输出64bit的密文
int subkeys[16][48]; //16个子密钥(48bit的K_i)
int chartobit[64] = { 0 };
int key[64];
int l[17][32], r[17][32];
CharToBit(input, chartobit);//将输入的明文消息转换为64个二进制数
IP(chartobit, Ip, IP_Table);//IP初始置换
CharToBit(key_in, key);//将输入的初始密钥转换为二进制数
subKey_fun(key, subkeys);//密钥生成
//第0轮中的IP置换后分为左右两部分
for (int i = 0; i < 32; i++)
{
l[0][i] = Ip[i];
r[0][i] = Ip[32 + i];
}
for (int j = 1; j < 16; j++)//前15轮的操作
{
for (int k = 0; k < 32; k++)//每轮将右半部分直接赋值给下一轮左半部分
{
l[j][k] = r[j - 1][k];
}
F_func(r[j - 1], r[j], subkeys[j - 1]);//使用初始密钥(正序)
Xor(r[j], l[j - 1], 32);//将f函数与左半部分异或得到下一轮右半部分
}
int t = 0;
for (t = 0; t < 32; t++)//最后一轮的操作
{
r[16][t] = r[15][t]; //将第15轮的右半部分直接赋值给第16轮的右半部分
}
F_func(r[15], l[16], subkeys[15]);//使用第16个子密钥
Xor(l[16], l[15], 32);//将f函数与左半部分异或得到下一轮左半部分
for (t = 0; t < 32; t++)//合并左右半部分
{
output_1[t] = l[16][t];
output_1[32 + t] = r[16][t];
}
//IP逆置换
IP_In(output_1, output, IPR_Table);
};
//完成DES解密运算
static void DES_Dfun(int input[64], char key_in[8], char output[8])
{
int Ip[64] = { 0 };//存储初始置换后的矩阵
int output_1[64] = { 0 };
int output_2[64] = { 0 };
int subkeys[16][48];
int chartobit[64] = { 0 };
int key[64];
int l[17][32], r[17][32];
IP(input, Ip, IP_Table);//正确,IP初始置换!
CharToBit(key_in, key);//正确!
subKey_fun(key, subkeys);//正确!
for (int i = 0; i < 32; i++)
{
l[0][i] = Ip[i];
r[0][i] = Ip[32 + i];
}
for (int j = 1; j < 16; j++)//前15轮的操作
{
for (int k = 0; k < 32; k++)
{
l[j][k] = r[j - 1][k];
}
F_func(r[j - 1], r[j], subkeys[16 - j]);//使用初始密钥(倒序)
Xor(r[j], l[j - 1], 32);
}
int t = 0;
for (t = 0; t < 32; t++)//最后一轮的操作
{
r[16][t] = r[15][t];
}
F_func(r[15], l[16], subkeys[0]);
Xor(l[16], l[15], 32);
for (t = 0; t < 32; t++)
{
output_1[t] = l[16][t];
output_1[32 + t] = r[16][t];
}
IP_In(output_1, output_2, IPR_Table);
BitToChar(output_2, output);
};
int main()
{
int output[64] = { 0 };
char MIN[9] = { 0 }; // 明文
char MI[9] = { 0 }; //秘钥
printf("请输入明文(8个字符):");
gets(MIN);
printf("请输入秘钥(8个字符):");
gets(MI);
DES_Efun(MIN, MI, output);
printf("密文如下:\n");
for (int i = 0; i < 64; i++)
{
printf("%d", output[i]);
if ((i + 1) % 4 == 0)
printf("\n");
}
printf("\n");
printf("解密功能\n");
DES_Dfun(output, MI, MIN);
printf("明文如下:\n");
for (int i = 0; i < 8; i++)
{
printf("%c", MIN[i]);
}
printf("\n");
return 0;
}
(2)openSSL库
调用函数,实现一个分组的加解密(DES-ECB模式)
#include <iostream>
#include "openssl/des.h"
using namespace std;
/*
* DES-ECB模式加解密测试
*/
int main() {
//明文
unsigned char data[]="1234567";
//密钥
unsigned char key[]="abcdefg";
//密文
unsigned char cip[]={0};
//输出
unsigned char out[]={0};
DES_key_schedule key_sch; //实际存储密钥
//密钥生成
DES_set_key((const_DES_cblock*)&key,&key_sch);
//加密
DES_ecb_encrypt((const_DES_cblock*)&data,(DES_cblock*)&cip,&key_sch,DES_ENCRYPT);
cout << "密文:"<<cip<<endl;
//解密
DES_ecb_encrypt((const_DES_cblock*)&cip,(DES_cblock*)&out,&key_sch,DES_DECRYPT);
cout << "明文:" <<out<<endl;
return 0;
}
AES#
Advanced Encryption Standard,起初是Square算法,然后是Rijndael算法,第三轮确定为AES。
算法 | 密钥长度 | 分组长度 | 轮数 |
---|---|---|---|
AES-128 | 128bit | 128bit | 10 |
AES-192 | 192bit | 128bit | 12 |
AES-256 | 256bit | 128bit | 14 |
AES的处理单位是字节,一般明文分组用字节为单位的矩阵表示,称为“状态矩阵(Status)”(从上到下,从左到右)四行(32bit),
如上面所示,每列称为一个32bit的“字”,所以在AES中:32bit = 4个字节 =1个”字“
另外初始密钥也是类似用一个矩阵表示,四行(32bit),
迭代轮数
下面以AES-128为例介绍:
加密#
- 轮函数
加密主要分为10轮,前9轮都是一样的,分为:字节代换、行移位、列混合和轮密钥加,最后一轮执行列混合,另外在第一轮开始前,先将明文与初始密钥进行一次轮密钥加。
轮函数的代码为:
AddRoundKey(State, RoundKey); //轮密钥加
//前9轮
Round(State, RoundKey){
ByteSub(State); //字节代换
ShiftRow(State); //行移位
MixColumn(State); //列混合
AddRoundKey(State, RoundKey); //轮密钥加
}
//第10轮
FinalRound(State, RoundKey){
ByteSub(State); //字节代换
ShiftRow(State); //行移位
AddRoundKey(State, RoundKey); //轮密钥加
}
字节代换#
字节代换是对单个字节做非线性的变换,操作是可逆的,记为
(1)两种变换
- 首先,将字节看作是
上的元素,即转换成一个多项式,然后计算出该多项式的乘法逆元,其中 的乘法逆元是自己。
- 然后对字节做仿射变换:
(2)查(S盒)表
一个字节的高四位为行,低四位为列
下面是一个字节代换的例子:
行移位#
行移位(ShiftRow)就是将状态矩阵各行进行循环移位,不同行的移位量是不同的。移位量
例如:
列混合#
列混合(MixColumn)是将状态矩阵的每列看作是一个
例如:
轮密钥加#
密钥加(AddRoundKey)就是将轮密钥与状态矩阵逐比特异或,即128bit的状态和128bit的密钥逐位异或,其中轮密钥就是由初始密钥通过密钥编排算法得到。
加密算法#
Enc(State, CipherKey)
KeyExpansion (CipherKey, ExpandedKey);//密钥编排算法
AddRoundKey (State, ExpandedKey);//轮密钥加
For (i=l; i<10; i++) Round (State, ExpandedKey + 4 * i);//轮函数
FinalRound (State, ExpandedKey + 4 * 10)//轮密钥加
}
密钥编排#
密钥编排就是从初始密钥得到轮密钥的过程,分为密钥扩展和轮密钥选取两部分。
密钥扩展#
密钥扩展就是从一个初始密钥中生成多重密钥以代替使用耽搁密钥,大大增加了比特位的扩散。
输入4字,输出44字,即输入128bit,输出11*128bit
- 输入128bit(4个字)的初始密钥,将其转换为一个
的矩阵,每列为一个矩阵,依次为 。 - 密钥扩展就是从
中扩展出 ,主要分为两种情况:- 对于下标不是4的倍数的,即对于
,其中 时 ,例如
- 对于下标是4的倍数的,即对于
,其中 时 ,其中 是一个函数,由三部分组成:字循环、字节代换和轮常量异或- 字循环:将一个“字”(4字节)左循环移1位,即
- 字节代换:将一个“字”(4字节)输入到S盒中代换,得到新的一个“字”(4字节)
- 轮常量异或:将字节代换后的一个“字”(4字节)和轮常量
异或,其中每轮的轮常量 均不同,这是为了防止不同轮中产生的轮密钥的对称性和相似性。
- 字循环:将一个“字”(4字节)左循环移1位,即
- 对于下标不是4的倍数的,即对于
轮密钥选取#
由密钥扩展得到44个“字”,即
1轮:
....
10轮:
满足:第
解密#
解密与加密结构相同,只是将各计算部件换为对应的逆部件,例如:
-
逆字节变换:InvByteSub
-
逆行移位:InvShiftRow
-
逆列混合:InvMixColumn
-
逆轮密码加:AddRoundKey(InvKey)
轮函数算法:
AddRoundKey(State, RoundKey); //轮密钥加
//前9轮
InvRound(State, RoundKey){
InvByteSub(State); //字节代换
InvShiftRow(State); //行移位
InvMixColumn(State); //列混合
AddRoundKey(State, RoundKey); //轮密钥加
}
//第10轮
InvFinalRound(State, RoundKey){
InvByteSub(State); //字节代换
InvShiftRow(State); //行移位
AddRoundKey(State, RoundKey); //轮密钥加
}
设加密算法的轮密钥为:
则解密算法的轮密钥为:
例子#
(1)实现加解密测试(128,192,256)和分组模式测试(ECB、CBC、OFB)
#include <iostream>
#include <iomanip>
#include "AES.h"
using namespace std;
void enc_Test()
{
int choose=0;
cout<<endl<<"加解密测试-选择:"
"1:AES-128bit-10轮;"
"2:AES-192bit-12轮"
"3:AES-256bit-14轮"<<endl;
cin>>choose;
const unsigned int BLOCK_BYTES_LENGTH = 16 * sizeof(unsigned char);
if(choose==1)
{
cout<<"-----------------------------AES-128bit-10轮-----------------------------"<<endl;
AES aes(AESKeyLength::AES_128);
cout<<"明文:";
unsigned char plain[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)plain[i]<<" ";
cout<<endl<<"密钥:";
unsigned char key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)key[i]<<" ";
cout<<endl<<"加密后:";
unsigned char *cip = aes.EncryptECB(plain, BLOCK_BYTES_LENGTH, key);
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)cip[i]<<" ";
cout<<endl<<"解密后:";
unsigned char *out = aes.DecryptECB(cip,BLOCK_BYTES_LENGTH, key);
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)out[i]<<" ";
} else if(choose==2)
{
cout<<"-----------------------------AES-192bit-12轮-----------------------------"<<endl;
const unsigned int BLOCK_BYTES_LENGTH = 16 * sizeof(unsigned char);
AES aes(AESKeyLength::AES_192);
cout<<"明文:";
unsigned char plain[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)plain[i]<<" ";
cout<<endl<<"密钥:";
unsigned char key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17};
for(int i=0;i<24;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)key[i]<<" ";
cout<<endl<<"加密后:";
unsigned char *cip = aes.EncryptECB(plain, BLOCK_BYTES_LENGTH, key);
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)cip[i]<<" ";
cout<<endl<<"解密后:";
unsigned char *out = aes.DecryptECB(cip,BLOCK_BYTES_LENGTH, key);
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)out[i]<<" ";
}else if(choose==3)
{
cout<<"-----------------------------AES-256bit-14轮-----------------------------"<<endl;
const unsigned int BLOCK_BYTES_LENGTH = 16 * sizeof(unsigned char);
AES aes(AESKeyLength::AES_256);
cout<<"明文:";
unsigned char plain[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff};
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)plain[i]<<" ";
cout<<endl<<"密钥:";
unsigned char key[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f};
for(int i=0;i<32;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)key[i]<<" ";
cout<<endl<<"加密后:";
unsigned char *cip = aes.EncryptECB(plain, BLOCK_BYTES_LENGTH, key);
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)cip[i]<<" ";
cout<<endl<<"解密后:";
unsigned char *out = aes.DecryptECB(cip,BLOCK_BYTES_LENGTH, key);
for(int i=0;i<16;i++)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)out[i]<<" ";
}else
cout<<"输入错误!"<<endl;
}
//模式测试
void modles_Test()
{
int choose=0;
cout<<endl<<"分组模式测试-选择:"
"1:AES-ECB-128bit;"
"2:AES-CBC-128bit"
"3:AES-CFB-128bit"<<endl;
cin>>choose;
const unsigned int BLOCK_BYTES_LENGTH = 16 * sizeof(unsigned char);
if(choose==1)
{
cout<<"-----------------------------AES-ECB-128bit-----------------------------"<<endl;
AES aes(AESKeyLength::AES_128);
cout<<"明文:";
vector<unsigned char> plain = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff};
for(auto i:plain)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
cout<<endl<<"密钥:";
vector<unsigned char> key = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
for(auto i:key)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
cout<<endl<<"加密后:";
vector<unsigned char> cip = aes.EncryptECB(plain, key);
for(auto i:cip)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
cout<<endl<<"解密后:";
vector<unsigned char> out = aes.DecryptECB(cip, key);
for(auto i:out)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
} else if(choose==2)
{
cout<<"-----------------------------AES-CBC-128bit-----------------------------"<<endl;
AES aes(AESKeyLength::AES_128);
cout<<"明文:";
vector<unsigned char> plain = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff};
for(auto i:plain)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
vector<unsigned char> iv = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff}; //初始化向量
cout<<endl<<"密钥:";
vector<unsigned char> key = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
for(auto i:key)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
cout<<endl<<"加密后:";
vector<unsigned char> cip = aes.EncryptCBC(plain, key, iv);
for(auto i:cip)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
cout<<endl<<"解密后:";
vector<unsigned char> out = aes.DecryptCBC(cip, key, iv);
for(auto i:out)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
}else if(choose==3)
{
cout<<"-----------------------------AES-CFB-128bit-----------------------------"<<endl;
AES aes(AESKeyLength::AES_128);
cout<<"明文:";
vector<unsigned char> plain = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb,
0xcc, 0xdd, 0xee, 0xff};
for(auto i:plain)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
vector<unsigned char> iv = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff}; //初始化向量
cout<<endl<<"密钥:";
vector<unsigned char> key = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
0x0b, 0x0c, 0x0d, 0x0e, 0x0f};
for(auto i:key)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
cout<<endl<<"加密后:";
vector<unsigned char> cip = aes.EncryptCFB(plain, key, iv);
for(auto i:cip)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
cout<<endl<<"解密后:";
vector<unsigned char> out = aes.DecryptCFB(cip, key, iv);
for(auto i:out)
cout<<setfill('0')<<setw(2)<<hex<<(unsigned int)i<<" ";
}else
cout<<"输入错误!"<<endl;
}
int main() {
enc_Test();
cout<<endl;
modles_Test();
return 0;
}
作者:Hang Shao
出处:https://www.cnblogs.com/pam-sh/p/16790995.html
版权:本作品采用「知识共享」许可协议进行许可。
声明:欢迎交流! 原文链接 ,如有问题,可邮件(mir_soh@163.com)咨询.
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 【.NET】调用本地 Deepseek 模型
2020-10-14 eclipse 配置opencv