第一章 引言
知识点
1.掌握密码算法安全性的分类
(1)理论安全性(也称为无条件安全性):即使密码分析者具有无穷的计算资源以及密文,都没有足够的信息恢复出明文。
(2)计算安全性:如果算法用现在的或者未来的可用资源都不能破译,那么就称为是就计算安全性。
(3)可证明安全性:密码可归约为某个经过深入研究的数学问题,数学问题被证明求解困难
2.清楚密码分析的难易程度
(1)唯密文攻击:这是最困难的攻击类型,敌手只能知道加密算法,以及截获的部分密文。使用穷举攻击法。
(2)已知明文攻击:知道加密算法,截获的密文,以及一些明-密文对。
(3)选择明文攻击:知道加密算法,截获的密文,以及选择明文并得到相应的密文。常用于破解使用公开加密系统加密的信息内容。
(4)选择密码攻击:知道加密算法,截获密文,以及选择密文并得到相应的明文,攻击者在这种情况下想要得到的是用户的秘钥
3.凯撒密码
(1)加密代换
c = E 3 ( m ) ≡ m + k ( m o d 26 ) , 0 ⩽ m ⩽ 25 c = E_3{}(m)\equiv m + k(mod 26), 0 \leqslant m \leqslant 25 c=E3(m)≡m+k(mod26),0⩽m⩽25
(2)解密代换
m = D 3 ( c ) ≡ c − 3 ( m o d 26 ) , 0 ⩽ c ⩽ 25 m = D_3{}(c) \equiv c - 3(mod 26), 0 \leqslant c \leqslant 25 m=D3(c)≡c−3(mod26),0⩽c⩽25
(3)说明
其中,3是加解密所用的密钥,加密时,每个字母向后移3位(循环移位,字母 x 移到 a , y 移到 b , z 移到 c )。解密时,每个字母向前移3位(循环移位)。
(4)代码实现(C++)
#define _CRT_SECURE_NO_WARNINGS 1
#include <bits/stdc++.h>
using namespace std;
//凯撒密码
//加密
void encrypt()
{
string s;
cout << "请输入需要加密的密文:";
cin >> s;
int k;
cout << "请输入密钥:";
cin >> k;
for (int i = 0; i < s.size(); i++)
{
if (s[i] >= 'a' && s[i] <= 'z')
{
s[i] = (s[i] - 'a' + k) % 26 + 'a';
}
if (s[i] >= 'A' && s[i] <= 'Z')
{
s[i] = (s[i] - 'A' + k) % 26 + 'A';
}
}
cout << "加密后的:";
cout << s;
cout << endl;
}
//解密
void decrypt()
{
string s;
cout << "请输入需要解密的明文:";
cin >> s;
int k;
cout << "请输入密钥:";
cin >> k;
for (int i = 0; i < s.size(); i++)
{
if (s[i] >= 'a' && s[i] <= 'z')
{
s[i] = (s[i] - 'a' - k) % 26 + 'a';
}
if (s[i] >= 'A' && s[i] <= 'Z')
{
s[i] = (s[i] - 'A' - k) % 26 + 'A';
}
}
cout << "解密后的:";
cout << s;
cout << endl;
}
int main()
{
cout << "凯撒密码" << endl;
cout << "1.加密 2.解密 3.退出" << endl;
while (1)
{
int m;
cout << "请输入你的选择:";
cin >> m;
if (m == 1)encrypt();
else if (m == 2)decrypt();
else if (m == 3)break;
else
cout << "你输入的代码有误,请重新输入:";
cout << "1.加密 2.解密 3.退出" << endl;
}
return 0;
}
这里面的代码是自己写的,密钥设置的是可以自由输入的,没有固定为3
4.仿射变换
(1)加密:
c = E a , b ( m ) ≡ a m + b ( m o d 26 ) c = E_a,_ b{}(m) \equiv am + b(mod 26) c=Ea,b(m)≡am+b(mod26)
(2)解密:
m = D a , b ( c ) ≡ a − 1 ( c − b ) ( m o d 26 ) m = D_a,_b{}(c) \equiv a^{-1} (c - b) (mod 26) m=Da,b(c)≡a−1(c−b)(mod26)
(3)说明:
其中 a 和 b 是密钥,为满足 0 ⩽ a 0\leqslant a 0⩽a , b ⩽ 25 b \leqslant 25 b⩽25 和 g c d ( a , 26 ) = 1 gcd(a,26) = 1 gcd(a,26)=1 的整数。其中 g c d ( a , 26 ) gcd(a,26) gcd(a,26) 表示 a 和 26 的最大公因子, g c d ( a , 26 ) = 1 gcd(a,26) = 1 gcd(a,26)=1 表示 a 和 26 是互素的, a − 1 a^{-1} a−1 表示 a 的逆元, a − 1 ⋅ a ≡ 1 m o d 26 a^{-1} \cdot a \equiv 1 mod 26 a−1⋅a≡1mod26。
(4)代码实现(C++)
#include <bits/stdc++.h>
using namespace std;
// 求a在mod 26下的逆元,如果不存在则返回-1
int find_inverse(int a) {
for (int i = 0; i < 26; i++) {
if ((i * a) % 26 == 1) {
return i;
}
}
return -1;
}
// 加密
string affineEncrypt(int a, int b, string plaintext) {
string ciphertext;
for (int i = 0; i < plaintext.length(); i++) {
if (isalpha(plaintext[i])) {
char c = toupper(plaintext[i]);
int x = c - 'A';
int y = (a * x + b) % 26;
if (isupper(plaintext[i])) {
ciphertext += char(y + 'A');
}
else {
ciphertext += char(y + 'a');
}
}
else {
ciphertext += plaintext[i];
}
}
return ciphertext;
}
// 解密
string affineDecrypt(int a, int b, string ciphertext) {
string plaintext;
int a_inverse = find_inverse(a);
if (a_inverse == -1) {
return "错误:a不存在逆元!";
}
for (int i = 0; i < ciphertext.length(); i++) {
if (isalpha(ciphertext[i])) {
char c = toupper(ciphertext[i]);
int y = c - 'A';
int x = (a_inverse * (y - b + 26)) % 26;
if (isupper(ciphertext[i])) {
plaintext += char(x + 'A');
}
else {
plaintext += char(x + 'a');
}
}
else {
plaintext += ciphertext[i];
}
}
return plaintext;
}
// 主函数
int main() {
int a, b; // 用于加密和解密的参数
string plaintext, ciphertext, decryptedtext;
int choice; // 用户选择的操作
cout << "欢迎使用仿射变换加密系统!" << endl;
while (true) {
cout << "\n请选择操作:" << endl;
cout << "1. 加密" << endl;
cout << "2. 解密" << endl;
cout << "3. 退出" << endl;
cin >> choice;
if (choice == 1) { // 加密
cout << "请输入明文:" << endl;
cin.ignore();
getline(cin, plaintext);
cout << "请输入加密参数a和b:" << endl;
cin >> a >> b;
ciphertext = affineEncrypt(a, b, plaintext);
cout << "密文是:" << ciphertext << endl;
}
else if (choice == 2) { // 解密
cout << "请输入密文:" << endl;
cin.ignore();
getline(cin, ciphertext);
cout << "请输入加密参数a和b:" << endl;
cin >> a >> b;
decryptedtext = affineDecrypt(a, b, ciphertext);
cout << "解密后的明文是:" << decryptedtext << endl;
}
else if (choice == 3) { // 退出
break;
}
else { // 错误处理
cout << "无效操作!请重新选择。" << endl;
}
}
return 0;
}
5.多表代换密码
(1)将明文 M 分为 n (矩阵 A 的行数)个字母构成的分组
(2)分别对每个分组加密
C
i
≡
A
M
i
+
B
(
m
o
d
N
)
,
i
=
1
,
2
,
⋯
,
j
C_i \equiv AM_i + B(mod N),i = 1,2,\cdots ,j
Ci≡AMi+B(modN),i=1,2,⋯,j
其中(A,B)是密钥,A 是 n * n 的可逆矩阵,满足
g
c
d
(
∣
A
∣
,
N
)
=
1
gcd(|A|,N) = 1
gcd(∣A∣,N)=1 (|A| 是行列式)。
B
=
(
B
1
,
B
2
,
⋯
,
B
n
)
T
,
C
=
(
C
1
,
C
2
,
⋯
,
C
n
)
T
,
M
i
=
(
m
1
,
m
2
,
⋯
,
m
n
)
T
B = (B _1,B_2,\cdots ,B_n)^{T},C = (C _1,C_2,\cdots ,C_n)^{T},M_i = (m _1,m_2,\cdots ,m_n)^{T}
B=(B1,B2,⋯,Bn)T,C=(C1,C2,⋯,Cn)T,Mi=(m1,m2,⋯,mn)T
(3)对密文分组
C
i
C_i
Ci 的 解密为:
M
i
=
A
−
1
(
C
i
−
B
)
(
m
o
d
N
)
,
i
=
1
,
2
,
⋯
,
j
M_i = A^{-1}(C_i-B)(mod N),i = 1,2,\cdots ,j
Mi=A−1(Ci−B)(modN),i=1,2,⋯,j
(4)代码实现(C++):
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 加密函数
string encrypt(string plaintext, vector<int> key) {
int m = key.size();
int n = plaintext.length() / m;
if (plaintext.length() % m != 0) {
n++;
}
// 将明文分组
vector<string> groups(n);
int k = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (k < plaintext.length()) {
groups[i].push_back(plaintext[k]);
}
else {
groups[i].push_back(' ');
}
k++;
}
}
// 根据密钥进行置换
string ciphertext;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
int index = (key[i] - 1) * n + j;
if (index < plaintext.length()) {
ciphertext.push_back(groups[j][i]);
}
else {
ciphertext.push_back(' ');
}
}
}
return ciphertext;
}
// 解密函数
string decrypt(string ciphertext, vector<int> key) {
int m = key.size();
int n = ciphertext.length() / m;
// 根据密钥进行逆置换
vector<int> inv_key(m);
for (int i = 0; i < m; i++) {
inv_key[key[i] - 1] = i + 1;
}
string plaintext;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
int index = i * m + inv_key[j] - 1;
if (index < ciphertext.length()) {
plaintext.push_back(ciphertext[index]);
}
else {
plaintext.push_back(' ');
}
}
}
return plaintext;
}
int main() {
string plaintext = "ming chen jiu dian fa dong fan gong"; // 明文信息
vector<int> key = { 3, 4, 2, 1 }; // 密钥
string ciphertext = encrypt(plaintext, key); // 加密
string decryptedtext = decrypt(ciphertext, key); // 解密
cout << "明文信息: " << plaintext << endl;
cout << "密钥: ";
for (int i = 0; i < key.size(); i++) {
cout << key[i] << " ";
}
cout << endl;
cout << "加密后的密文: " << ciphertext << endl;
cout << "解密后的明文: " << decryptedtext << endl;
return 0;
}
6.凯撒密码的加密原理
(1)caesar属于什么类型的密码?单表代换,他是经典的古典密码算法之一。
(2)单表代换:利用预先设定好的固定的代换规则,对明文逐字符或逐字符组进行代换的密码。固定:指的是代换规则只有一种,因而与密钥和被加密的明文字符的序号无关。相同的明文字符组,一定产生相同的密文字符组。
(3)Caeser密码加密中,明文中所有字母都是按照一个固定的位数进行偏移后加密成密文。 Caeser密码的密钥是 移动的位数。
(4)对明文字符进行caeser密码加密,相同的明文字符组一定会变成相同的密文字符组。
(5)caeser是一种对英文字母进行逐字母加密的密码。
(6)将英文字母转换为该字母的序号,从0开始。
加密变换:c = (m+3)%26 解密变换是 m = (c-3)%26。
将明文 cipher->密文 flskhu.
(7)单表代换密码的优缺点:
优点:明文字符转换成密文字符形态发生变化。
缺点:明文字符的位置没有发生变化,明文字符的统计规律完全暴露于密文字符中。
习题
例题(1-2)
设 n = 3, N = 26, A = ( 11 2 19 5 23 25 20 7 17 ) , B = ( 0 0 0 ) A = \begin{pmatrix} 11 & 2 & 19\\ 5& 23 & 25\\ 20& 7 &17 \end{pmatrix} , B = \begin{pmatrix} 0\\ 0\\ 0 \end{pmatrix} A= 115202237192517 ,B= 000 明文为 YOUR PIN NO IS FOUR ONE TWO SIX。
解:
(1)加密:
将明文分成 3 个字母组成的分组YOU RPI NNO ISF OUR ONE TWO SIX,由英文字母和十进制数字对应关系得:
M
1
=
(
24
14
20
)
,
M
2
=
(
17
15
8
)
,
M
3
=
(
13
13
14
)
,
M
4
=
(
8
18
5
)
M_1 = \begin{pmatrix} 24\\ 14\\ 20 \end{pmatrix},M_2 = \begin{pmatrix} 17\\ 15\\ 8 \end{pmatrix},M_3 = \begin{pmatrix} 13\\ 13\\ 14 \end{pmatrix}, M_4 = \begin{pmatrix} 8\\ 18\\ 5 \end{pmatrix}
M1=
241420
,M2=
17158
,M3=
131314
,M4=
8185
M
5
=
(
14
20
17
)
,
M
6
=
(
14
13
4
)
,
M
7
=
(
19
22
14
)
,
M
8
=
(
18
8
23
)
M_5 = \begin{pmatrix} 14\\ 20\\ 17 \end{pmatrix},M_6 = \begin{pmatrix} 14\\ 13\\ 4 \end{pmatrix},M_7 = \begin{pmatrix} 19\\ 22\\ 14 \end{pmatrix}, M_8 = \begin{pmatrix} 18\\ 8\\ 23 \end{pmatrix}
M5=
142017
,M6=
14134
,M7=
192214
,M8=
18823
所以
C
1
=
A
(
24
14
20
)
=
(
22
6
8
)
,
C
2
=
A
(
17
15
8
)
=
(
5
6
9
)
,
C
3
=
A
(
13
13
14
)
=
(
19
12
17
)
C_1 = A\begin{pmatrix} 24\\ 14\\ 20 \end{pmatrix}=\begin{pmatrix} 22\\ 6\\ 8 \end{pmatrix},C_2 = A\begin{pmatrix} 17\\ 15\\ 8 \end{pmatrix}=\begin{pmatrix} 5\\ 6\\ 9 \end{pmatrix},C_3 = A\begin{pmatrix} 13\\ 13\\ 14 \end{pmatrix}=\begin{pmatrix} 19\\ 12\\ 17 \end{pmatrix}
C1=A
241420
=
2268
,C2=A
17158
=
569
,C3=A
131314
=
191217
C
4
=
A
(
8
18
5
)
=
(
11
7
7
)
,
C
5
=
A
(
14
20
17
)
=
(
23
19
7
)
,
C
6
=
A
(
14
13
4
)
=
(
22
1
23
)
C_4 = A\begin{pmatrix} 8\\ 18\\ 5 \end{pmatrix}=\begin{pmatrix} 11\\ 7\\ 7 \end{pmatrix},C_5 = A\begin{pmatrix} 14\\ 20\\ 17 \end{pmatrix}=\begin{pmatrix} 23\\ 19\\ 7 \end{pmatrix},C_6 = A\begin{pmatrix} 14\\ 13\\ 4 \end{pmatrix}=\begin{pmatrix} 22\\ 1\\ 23 \end{pmatrix}
C4=A
8185
=
1177
,C5=A
142017
=
23197
,C6=A
14134
=
22123
C
7
=
A
(
19
22
14
)
=
(
25
15
18
)
,
C
8
=
A
(
18
8
23
)
=
(
1
17
1
)
C_7 = A\begin{pmatrix} 19\\ 22\\ 14 \end{pmatrix}=\begin{pmatrix} 25\\ 15\\ 18 \end{pmatrix},C_8 = A\begin{pmatrix} 18\\ 8\\ 23 \end{pmatrix}=\begin{pmatrix} 1\\ 17\\ 1 \end{pmatrix}
C7=A
192214
=
251518
,C8=A
18823
=
1171
密文为 WGI FGJ TMR LHH XTH WBX ZPS BRB。
(2)解密:
A
−
1
=
(
11
2
19
5
23
25
20
7
17
)
=
(
10
23
7
15
9
22
5
9
21
)
A^{-1} = \begin{pmatrix} 11 & 2 & 19\\ 5& 23 & 25\\ 20&7 & 17 \end{pmatrix}=\begin{pmatrix} 10 &23 &7 \\ 15 & 9 &22 \\ 5 & 9 &21 \end{pmatrix}
A−1=
115202237192517
=
10155239972221
则
M
1
=
A
−
1
(
22
6
8
)
=
(
24
14
20
)
,
M
2
=
A
−
1
(
5
6
9
)
=
(
17
15
8
)
,
M
3
=
A
−
1
(
19
12
17
)
=
(
13
13
14
)
M_1=A^{-1}\begin{pmatrix} 22\\ 6\\ 8 \end{pmatrix}=\begin{pmatrix} 24\\ 14\\ 20 \end{pmatrix},M_2=A^{-1}\begin{pmatrix} 5\\ 6\\ 9 \end{pmatrix}=\begin{pmatrix} 17\\ 15\\ 8 \end{pmatrix},M_3=A^{-1}\begin{pmatrix} 19\\ 12\\ 17 \end{pmatrix}=\begin{pmatrix} 13\\ 13\\ 14 \end{pmatrix}
M1=A−1
2268
=
241420
,M2=A−1
569
=
17158
,M3=A−1
191217
=
131314
M
4
=
A
−
1
(
11
7
7
)
=
(
8
18
5
)
,
M
5
=
A
−
1
(
23
19
7
)
=
(
14
20
17
)
,
M
6
=
A
−
1
(
22
1
23
)
=
(
14
13
4
)
M_4=A^{-1}\begin{pmatrix} 11\\ 7\\ 7 \end{pmatrix}=\begin{pmatrix} 8\\ 18\\ 5 \end{pmatrix},M_5=A^{-1}\begin{pmatrix} 23\\ 19\\ 7 \end{pmatrix}=\begin{pmatrix} 14\\ 20\\ 17 \end{pmatrix},M_6=A^{-1}\begin{pmatrix} 22\\ 1\\ 23 \end{pmatrix}=\begin{pmatrix} 14\\ 13\\ 4 \end{pmatrix}
M4=A−1
1177
=
8185
,M5=A−1
23197
=
142017
,M6=A−1
22123
=
14134
M
7
=
A
−
1
(
25
15
18
)
=
(
19
22
14
)
,
M
8
=
A
−
1
(
1
17
1
)
=
(
18
8
23
)
M_7=A^{-1}\begin{pmatrix} 25\\ 15\\ 18 \end{pmatrix}=\begin{pmatrix} 19\\ 22\\ 14 \end{pmatrix},M_8=A^{-1}\begin{pmatrix} 1\\ 17\\ 1 \end{pmatrix}=\begin{pmatrix} 18\\ 8\\ 23 \end{pmatrix}
M7=A−1
251518
=
192214
,M8=A−1
1171
=
18823
得明文为YOU RPI NNO ISF OUR ONE TWO SIX。
2.设由仿射变换对一个明文加密得到的密文为 edsgickxhuklzveqzvkxwkzukvcuh 又已知明文的前两个字符是 if。对该密文解密。
解:
第二章 流密码
知识点
1.流密码的组成和特点
(1)组成
根据加密器中记忆元件的存储状态 δ i \delta_i δi是否依赖于输入的明文字符,流密码可分为同步流密码与自同步流密码。
(2)特点
优点:处理速度快,实时性能好,错误传播小,实现电路简单,便于软硬件实施。
缺点是:明文扩散性差(意味着混乱不够),插入与修改数据不敏感,密钥需要同步
分组密码的特点:
优点:明文扩散性好,不需要秘钥同步。
缺点:加密速度慢,错误易扩散与传播。
流密码中产生密钥流的一个重要组成部分是 移位寄存器
2.流密码的基本思想
习题
第三章 分组密码
知识点
1.分组密码的CBC工作模式
它一次对一个明文分组进行加密,每次加密使用相同的密钥,加密算法的输入时这次明文分组与上一次密文分组的异或,因此加密算法的输入不会显示这是明文分组之间的固定关系,所以重复的明文分组不会在密文中暴露这种重复的关系。
2.AES中字节求逆