0%

信息安全原理与实践

待整理…

Ⅰ-加密

1. 加密基础

1.1 简单替换密码

​ 著名的凯撒密码。

1.2 双换位密码

  • 加密方法:将明文写在一个n*m的矩阵中,然后对行列根据特定的序列进行置换操作。

    举例:

1.3 一次性密码本

  • 采用随机密钥,Alice和Bob必须都知道加密时所用的密钥,这样对方才能破译出明文。

  • 密钥必须只能使用一次,连续使用会被对方用穷举法破译。

    加密: 明文 $\oplus$ 密钥 = 密文

    解密: 密文 $\oplus$ 密钥 = 明文

2-对称密钥加密

2.1 流密码加密

  • 用法等同于一次性密码本加密方法。

  • 密钥流通过密钥生成,简单看成以下公式:

    $StreamCipher(K) = S$ 其中$K$是密钥, $S$是生成的密钥流, $StreamCipher()$是密钥处理函数。

  • 给定密钥流$S = S_{0}, S_{1}, S_{2}, …$以及明文$P=P_{0},P_{1},P_{2},…$,通过按位异或运算生成密文$C=C_{0},C_{1},C_{2},…$,

    过程:$C_{0}=P_{0}\oplus S_{0},C_{1}=P_{1}\oplus S_{1},C_{2}=P_{2}\oplus S_{2},…$

  • 解密:$P_{0}=C_{0}\oplus S_{0},P_{1}=C_{1}\oplus S_{1},P_{2}=C_{2}\oplus S_{2},…$

  • $\textbf{$A5/1$算法} $

    三个寄存器$X、Y、Z$,其中$X$寄存器19位,$Y$寄存器22位,$Z$寄存器23位,一共64位。

    三个寄存器的步骤操作:

定义投票函数$maj(x,y,z)$,其中$x,y,z$为一位二进制,投票函数返回值为$x,y,z$中出现次数最多的那个值。

密钥流$S_{i}$的生成过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
/*
实现代码
语言:C++
*/
#include<iostream>
#include<string>
#include<algorithm>
#include<ctime>
using namespace std;
const int maxn = 1e5;
int P[maxn]; // 明文
int C[maxn]; // 密文
int S[maxn]; // 密钥流
int X[30]; // 19位X寄存器
int Y[30]; // 21位Y寄存器
int Z[30]; // 23位Z寄存器
int len; // 明文长度
int maj(int x, int y, int z){ return x+y+z>1;}
void shift(int tmp[], int num, int t){ for(int i=num-1;i>0;--i) tmp[i] = tmp[i-1];X[0]=t;}
void get_S(){
for(int i=0;i<len;++i){
int m = maj(X[8], Y[10], Z[10]);
if(X[8] ==m) shift(X,19,X[13]^X[16]^X[17]^X[18]);
if(Y[10]==m) shift(Y,22,Y[20]^Y[21]);
if(Z[10]==m) shift(Z,23,Z[7]^Z[20]^Z[21]^Z[22]);
S[i] = X[18]^Y[21]^Z[22];
}
}
void A5(int tmp_C[], int tmp_P[]){
for(int i=0;i<len;++i) tmp_P[i] = tmp_C[i]^S[i];
}
void random(){
srand(time(0));
cout<<"明文:";
for(int i=0;i<len;++i){
P[i] = rand()%2;
cout<<P[i]<<" ";
}cout<<"\n";
A5(P,C);
cout<<"密文:";for(int i=0;i<len;++i) cout<<C[i]<<" ";cout<<"\n";
A5(C,C);
cout<<"明文:";for(int i=0;i<len;++i) cout<<C[i]<<" ";cout<<"\n";
}
int main(){
freopen("in.in","r", stdin);
for(int i=0;i<19;++i) cin>>X[i];
for(int i=0;i<22;++i) cin>>Y[i];
for(int i=0;i<23;++i) cin>>Z[i];
cin>>len;
cout<<len<<endl;
for(int i=0;i<len;++i) cin>>P[i];
get_S();
cout<<"密钥流:";for(int i=0;i<len;++i) cout<<S[i]<<" ";cout<<"\n";
A5(P, C);
cout<<"密文:";for(int i=0;i<len;++i) cout<<C[i]<<" ";cout<<"\n";
A5(C, C);
cout<<"明文:";for(int i=0;i<len;++i) cout<<C[i]<<" ";cout<<"\n\n";
random();

}
  • $\textbf{RC4算法}$

  • 初始化阶段,用密钥初始化查找表。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    伪代码
    for i=0 to 255
    S[i] = i
    K[i] = key[i % N]
    next i
    j = 0
    for i = 0 to 255
    j = (j + S[i] + K[i]) % 256
    swap(S[i], S[j])
    next i
    i = j = 0
  • 每个密钥流字节依据算法逐步生成的过程

    1
    2
    3
    4
    5
    6
    伪代码
    i = (i + 1) % 256
    j = (j + S[i]) % 256
    swap(S[i], S[j])
    t = (S[i] + S[j]) % 256
    keystreamByte = S[t]
  • 密码流与A5-1算法的密码流一致,用于加密明文,解密密文。


2.2 分组密码加密

  • $\textbf{Feistel密码}$ :加密方案设计的通用原则。

    明文$P$被分成左右两部分:$P=(L_{0},R_{0})$

    对于第$i$轮加密,新的$L_{i},R_{i}$生成规则如下:

    $L_{i} = R_{i-1}$

    $R_{i}=L_{i-1} \oplus F(R_{i-1},K_{i})$

    $i=1,2,…,n$

    对于最后一轮加密,结果即为密文:$C=(L_{n},R_{n})$

    解密过程:

    $R_{i-1}=L_{i}$

    $L_{i-1}=R_{i} \oplus F(R_{i-1}, K_{i})$

    $i = n,n-1,…,1$

    对于最后一轮解密,结果即为明文:$P=(L_{0} \oplus R_{0})$

    $F(R_{i-1},k_{i})$为轮函数。

  • $\textbf{DES}$:数据加密标准

    • 共16轮计算
    • 64位分组长度
    • 56位密钥
    • 48位子密钥

    DES

轮函数$F$:$F(R_{i-1},K_{i})=Pbox(Sboxes(Expand(R_{i-1} \oplus K_{i})))$