密码学原理 Chapter 3——分组密码与高级密码标准

现代分组密码设计思想:
分组密码是一个{0,1}的随机代换
基本的变换手段为:代换与置换
基本的安全需求:混乱(密钥和明文以及密文之间的依赖关系复杂)、扩散(单个密钥位或明文位的影响尽可能扩散到更多的密文位,即修改明文的某一位需要尽可能导致密文的尽可能多位发生改变)
结构 - SPN网络和Feistel结构

迭代密码:将明文经过加密函数G迭代加密多次(需要密钥参与,密钥由密钥扩展算法生成,每一次加密的密钥都不相同)。多次加密能够使得比特位得到扩散,增加了密码的安全性。

**SPN网络——代换-置换网络的一轮变换过程:**明文X的一轮加密包含:代换S和置换P。首先与轮密钥异或(白化),然后首先进行小代换,然后将几组的代换结果经过置换后输出。解密首先反置换再反代换即可。如输入为16比特,则代换过程则是将这16比特分为4组,每组均进行代换操作(这些代换需要借助代换表完成)置换则是将代换后的16比特打乱重排后输出。不过 由于对于任意的线性变换A:x→y=A(x),有A(x ⊕ \oplus k)=A(x) ⊕ \oplus A(k),因此存在有不同的解密顺序也能够解密出正确结果。

Feistel结构的一轮变换过程:将输入分为两份,每一轮运算只运算了一半的输入,交替加密。流密钥函数K与一半不变的输入输入到函数F中,将得到的输出与另一半输入异或后输出。其加密与解密过程完全相同,不同的是解密密钥首先输入Kn到K0,加密密钥为K0到Kn,即逆序使用。非线性函数F不需要可逆。 Feistel的扩散速度比SPN网络慢,因此需要更多的迭代次数

SPN 密码体制定义

设l,m,Nr是正整数,P=C={0,1}lm
K ⊆ ( { 0 , 1 } l m ) N r + 1 K\subseteq(\{0,1\}^{lm})^{Nr+1} K({0,1}lm)Nr+1是由初始密钥k用密钥编排算法生成的所有可能的密钥编排方案集合,一个密钥编排方案记为(k1, k2, …, kNr+1)
状态值w长度为l×m,记为w1, w2, …, wNr+1
w可以看成m个长度为l的子串连接而成,记为w<1>,w<2>,…,w<m>,其中
w<i>=w(i-1)l+1,w(i-1)l+2,…,w(i-1)l+l

  • SPN的特点:结构简单,易于软硬件实现;高效快速,易于扩展和强化——增加l和m可以提高穷举k的难度(但过大可能会占用过多存储资源),也可以使用多个S盒和P盒进一步提高变换的复杂度,增加Nr可以进一步提高密文的混乱程度

线性密码分析

通过分析S盒的线性特性从而发现明文比特、密文比特和密钥比特之间可能存在的概率线性关系。存在一个比特子集使得其中元素的异或表现出非随机的分布来进行分析的密码分析方法。(已知明文攻击,给定明文、密文和S盒,确定k的部分比特)

S盒线性逼近

考虑一个S盒 π \pi πS:{0,1}m→{0,1}n,具有m重输入X=(x1,x2,…,xm)和n重输出Y=(y1,y2,…,yn)。从X和Y中任意选择若干比特通过异或运算构成一个随机变量
x i 1 ⊕ x i 2 ⊕ . . . ⊕ x i k ⊕ y j 1 ⊕ y j 2 ⊕ . . . ⊕ y j l x_{i_1}\oplus x_{i_2}\oplus...\oplus x_{i_k}\oplus y_{j_1}\oplus y_{j_2}\oplus...\oplus y_{j_l} xi1xi2...xikyj1yj2...yjl

上面的结果很可能不为二分之一,就产生了特殊的概率。

如果选择的输入序列X对应的输出不是Y,则 P r [ Y 1 = y 1 , . . . , Y n = y n ∣ X 1 = x 1 , . . . , X m = x m ] = 0 Pr[Y_1=y_1,...,Y_n=y_n|X_1=x_1,...,X_m=x_m]=0 Pr[Y1=y1,...,Yn=ynX1=x1,...,Xm=xm]=0,否则等于 2 − m 2^{-m} 2m

偏差

取值于{0,1}上的随机变量X,取值为0的概率为p,则取值为1的概率为1-p,X的偏差定义为: ϵ = p − 1 2 \epsilon=p-\frac{1}{2} ϵ=p21

堆积引理

X i 1 , X i 2 , . . . , X i k X_{i_1},X_{i_2},...,X_{i_k} Xi1,Xi2,...,Xik是取值于{0,1}上的独立随机变量,其偏差依次为 ϵ i 1 , . . . , ϵ i k \epsilon_{i_1},...,\epsilon_{i_k} ϵi1,...,ϵik,定义随机变量 X i 1 , i 2 , . . . , i k = X i 1 ⊕ X i 2 ⊕ . . . X i k X_{i_1,i_2,...,i_k}=X_{i_1}\oplus X_{i_2}\oplus...X_{i_k} Xi1,i2,...,ik=Xi1Xi2...Xik,以 ϵ i 1 , i 2 , . . . , i k \epsilon_{i_1,i_2,...,i_k} ϵi1,i2,...,ik表示其偏差,则有
ϵ i 1 , i 2 , . . . , i k = 2 k − 1 ∏ j = 1 k ϵ i j \epsilon_{i_1,i_2,...,i_k}=2^{k-1}\prod_{j=1}^k\epsilon_{i_j} ϵi1,i2,...,ik=2k1j=1kϵij

证明:当k=1时结论显然成立
假设k=n时上述结论成立,则当k=n+1时
P r [ X i 1 ⊕ . . . ⊕ X i n + 1 = 0 ] = P r [ X i 1 ⊕ . . . ⊕ X i n = 0 ] P r [ X i n + 1 = 1 ] + P r [ X i 1 ⊕ . . . ⊕ X i n = 1 ] P r [ X i n + 1 = 0 ] = ( 2 n − 1 ∏ ϵ i j + 1 2 ) ( ϵ i n + 1 + 1 2 ) + ( 1 2 − 2 n − 1 ∏ ϵ i j ) ( 1 2 − ϵ i n + 1 ) = 1 2 + 2 n ∏ ϵ i j Pr[X_{i_1}\oplus...\oplus X_{i_{n+1}}=0]=Pr[X_{i_1}\oplus...\oplus X_{i_{n}}=0]Pr[X_{i_{n+1}}=1]+Pr[X_{i_1}\oplus...\oplus X_{i_{n}}=1]Pr[X_{i_{n+1}}=0]\\ =(2^{n-1}\prod\epsilon_{i_j}+\frac{1}{2})(\epsilon_{i_{n+1}}+\frac{1}{2})+(\frac{1}{2}-2^{n-1}\prod\epsilon_{i_j})(\frac{1}{2}-\epsilon_{i_{n+1}})\\ =\frac{1}{2}+2^n\prod\epsilon_{i_j} Pr[Xi1...Xin+1=0]=Pr[Xi1...Xin=0]Pr[Xin+1=1]+Pr[Xi1...Xin=1]Pr[Xin+1=0]=(2n1ϵij+21)(ϵin+1+21)+(212n1ϵij)(21ϵin+1)=21+2nϵij
证毕。

线性逼近表:


a表示输入的4比特,b表示输出的4比特,中间的数字表示满足 ( ⊕ i = 1 4 a i X i ) ⊕ ( ⊕ i = 1 4 b i Y i ) = 0 (\oplus_{i=1}^{4}a_iX_i)\oplus(\oplus_{i=1}^4b_iY_i)=0 (i=14aiXi)(i=14biYi)=0 ( x 1 , x 2 , x 3 , x 4 , y 1 , y 2 , y 3 , y 4 ) (x_1,x_2,x_3,x_4,y_1,y_2,y_3,y_4) (x1,x2,x3,x4,y1,y2,y3,y4)的个数( ( y 1 , y 2 , y 3 , y 4 ) = π S ( x 1 , x 2 , x 3 , x 4 ) (y_1,y_2,y_3,y_4)=\pi_S(x_1,x_2,x_3,x_4) (y1,y2,y3,y4)=πS(x1,x2,x3,x4)),容易通过此表获取偏差。选择其中距离8最大的部分可得偏差最大的输入输出对。理解:线性逼近表是S盒的性质,仅与S盒的置换有关。

线性逼近分析过程


需要注意的是,线性分析只能攻击最后一个密钥,而不能攻击其他密钥,因此在分析过程中应将其他密钥视而不见,因为密钥是确定的,而偏差计算的是一种分布,与前面的密钥无关。输入和输出应尽量选择对应于线性逼近表中数值偏离8较多的,这样分析成功的概率更大。
对于第一轮S盒的输入,追踪其输出到最后并计算偏差

如上图中第一轮输入选B输出选4,则随机变量 T 1 = u 5 1 ⊕ u 7 1 ⊕ u 8 1 ⊕ v 6 1 T_1=u_5^1\oplus u_7^1\oplus u_8^1\oplus v_6^1 T1=u51u71u81v61的偏差为 1 4 \frac{1}{4} 41
第二轮输入选4输出选5的偏差绝对值最大。即随机变量 T 2 = u 6 2 ⊕ v 6 2 ⊕ v 8 2 T_2=u_6^2\oplus v_6^2\oplus v_8^2 T2=u62v62v82的偏差为 − 1 4 -\frac{1}{4} 41
第三轮输入需要注意,第二轮输入的最低位跑到第4个盒去了,所以第三轮输入考虑两个盒,一个是 S 3 2 S_3^2 S32,输入为4;一个是 S 3 4 S_3^4 S34,输入为4,输出还是都选5。即 T 3 = u 6 3 ⊕ v 6 3 ⊕ v 8 3 T_3=u_6^3\oplus v_6^3\oplus v_8^3 T3=u63v63v83偏差为 − 1 4 -\frac{1}{4} 41 T 4 = u 14 3 ⊕ v 14 3 ⊕ v 16 3 T_4=u_{14}^3\oplus v_{14}^3\oplus v_{16}^3 T4=u143v143v163偏差为 − 1 4 -\frac{1}{4} 41
T 1 ⊕ T 2 ⊕ T 3 ⊕ T 4 = x 5 ⊕ x 7 ⊕ x 8 ⊕ v 6 3 ⊕ v 8 3 ⊕ v 14 3 ⊕ v 16 3 ⊕ k 5 1 ⊕ k 7 1 ⊕ k 8 1 ⊕ k 6 2 ⊕ k 6 3 ⊕ k 14 3 = x 5 ⊕ x 7 ⊕ x 8 ⊕ u 6 4 ⊕ u 8 4 ⊕ u 14 4 ⊕ u 16 4 ⊕ k 5 1 ⊕ k 7 1 ⊕ k 8 1 ⊕ k 6 2 ⊕ k 6 3 ⊕ k 14 3 ⊕ k 6 4 ⊕ k 8 4 ⊕ k 14 4 ⊕ k 16 4 T_1\oplus T_2\oplus T_3\oplus T_4=x_5\oplus x_7\oplus x_8\oplus v_6^3\oplus v_8^3\oplus v^3_{14}\oplus v_{16}^3\oplus k_5^1\oplus k_7^1\oplus k_8^1\oplus k_6^2\oplus k_6^3\oplus k_{14}^3\\ =x_5\oplus x_7\oplus x_8\oplus u_6^4\oplus u_8^4\oplus u^4_{14}\oplus u_{16}^4\oplus k_5^1\oplus k_7^1\oplus k_8^1\oplus k_6^2\oplus k_6^3\oplus k_{14}^3\oplus k_6^4\oplus k_8^4\oplus k_{14}^4\oplus k_{16}^4 T1T2T3T4=x5x7x8v63v83v143v163k51k71k81k62k63k143=x5x7x8u64u84u144u164k51k71k81k62k63k143k64k84k144k164

由堆积引理可知 T 1 ⊕ T 2 ⊕ T 3 ⊕ T 4 T_1\oplus T_2\oplus T_3\oplus T_4 T1T2T3T4的偏差为 − 1 32 -\frac{1}{32} 321(四者并不独立,因此这不是准确值,只是估算,不过仍然有效), x 5 ⊕ x 7 ⊕ x 8 ⊕ u 6 4 ⊕ u 8 4 ⊕ u 14 4 ⊕ u 16 4 x_5\oplus x_7\oplus x_8\oplus u_6^4\oplus u_8^4\oplus u^4_{14}\oplus u_{16}^4 x5x7x8u64u84u144u164具有偏差 ± 1 32 ±\frac{1}{32} ±321(后面的k是固定不变的,因此不会计入偏差)

理解:这实际上是一个加密链的分析过程,上面的选择输入是由我们自由选择的,不是说输入就是这个,而是说我们选择哪些比特参与异或。

分析过程梳理:

  1. 收集尽可能多的在同一未知密钥k加密的T对明-密文对,用 T \mathbb T T表示明-密文对的集合( ∣ T ∣ = T |\mathbb T|=T T=T),目标是获得候选子密钥( k < 2 > 5 , k < 4 > 5 k_{<2>}^5,k_{<4>}^5 k<2>5,k<4>5,即4组子密钥中的第2组和第4组)
  2. 每个候选子密钥分配一个计数器,初始值为0
  3. 对于每对明-密文对,尝试所有可能的候选子密钥,计算随机变量 x 5 ⊕ x 7 ⊕ x 8 ⊕ u 6 4 ⊕ u 8 4 ⊕ u 14 4 ⊕ u 16 4 x_5\oplus x_7\oplus x_8\oplus u_6^4\oplus u_8^4\oplus u^4_{14}\oplus u_{16}^4 x5x7x8u64u84u144u164的结果,若结果为0则相应计数器加1
  4. 明-密文对尝试完毕后,真子密钥对应的计数值最接近 T 2 ± T 32 \frac{T}{2}±\frac{T}{32} 2T±32T,其他则接近 T 2 \frac{T}{2} 2T(T越大结果越准确)

线性密码分析基于S盒的有效线性逼近
是一种已知明文攻击方法,需要较多的明-密文对

  • 基于偏差 ε \varepsilon ε的线性攻击要想获得成功,所需明密文对数量T接近 c ε 2 c\varepsilon^2 cε2,c为常数
    此算法只能分析最后一轮子密钥,缩小的穷举密钥的范围。

差分密码分析

通过分析明文对的差值(异或)对密文对差值的影响来恢复某些密钥比特的分析方法。
一种选择明文攻击方法,构造若干明文串对,每对明文的异或相等,观察相应密文异或结果。

S盒差分特征

π S : { 0 , 1 } m → { 0 , 1 } n \pi_S:\{0,1\}^m\rightarrow \{0,1\}^n πS:{0,1}m{0,1}n是一个S盒,长为m的有序比特串对(x,x*),称S盒输入异或为 x ′ = x ⊕ x ∗ x'=x\oplus x^* x=xx,输出异或为 y ′ = π S ( x ) ⊕ π S ( x ∗ ) y'=\pi_S(x)\oplus\pi_S(x^*) y=πS(x)πS(x),(x’,y’)称为一对差分。
对于任意 x ′ ∈ { 0 , 1 } m x'\in\{0,1\}^m x{0,1}m,定义集合 Δ ( x ′ ) \Delta(x') Δ(x)为包含所有输入异或值为x’的有序对(x,x*),该集合含有2m对,对集合 Δ ( x ′ ) \Delta(x') Δ(x)中的每一对,可求出S盒的输出异或,一个非均匀的输出分布将会是一个成功差分分析的基础。

需要分析(x’, y’)的分布情况,其中x’是固定的。(注意每一个y’只会出现偶数次,因为x和x*互换后y和y*互换,然后y’相等)

扩散率: 条件概率 P r [ y ′ = b ∣ x ′ = a ] Pr[y'=b|x'=a] Pr[y=bx=a]称为差分(a,b)的扩散率 R p ( a , b ) R_p(a,b) Rp(a,b)
R p ( a , b ) = N D ( a , b ) 2 m R_p(a,b)=\frac{N_D(a,b)}{2^m} Rp(a,b)=2mND(a,b)

差分分析过程


上图中a表示输入x,b表示y’。

第一轮应该选择扩散率最大的进行分析,能够分析成功的概率最大。,扩散率为 1 2 \frac{1}{2} 21
第二轮追踪第一轮的输出,到了第三个子密钥中进行分析。输入选择4,输出选择6,扩散率为 3 8 \frac{3}{8} 83
接下来按照图中红线继续分析即可。 S 2 3 , S 3 3 S_2^3,S_3^3 S23,S33的扩散率均为 3 8 \frac{3}{8} 83

由图可知总的扩散率即为扩散率的乘积。

输入异或与子密钥无关,但输出有关

正确对:对于给定密钥,满足差分特征的明文对。对于所有明文输入,正确对产生的概率等于扩散率。

需要找到足够多的四元组(x,x*,y,y*),其中 x ⊕ x ∗ = x ′ x\oplus x^*=x' xx=x固定不变,和线性分析一样,只能分析最后一轮子密钥,对可能的候选子密钥进行猜测,正确对在正确的密钥作用下,满足差分链特征。
错误对:带来噪音

上例中测试最后一轮子密钥k5的8位,即穷举256个密钥。满足差分特征,则相应密钥的计数器加1

分析过程梳理

  • 收集尽可能多的在同一未知密钥k加密的T个4重组(x,x*,y,y*),x’=0000101100000000,用T表示四重组的集合(|T|=T),目标是获得候选子密钥 ( k < 2 > 5 , k < 4 > ) 5 (k_{<2>}^5,k_{<4>})^5 (k<2>5,k<4>)5
  • 每个候选子密钥分配一个计数器,初始值为0,
  • 对每对明-密文,尝试所有可能的候选子密钥,计算出 u ′ 4 u'^4 u′4,如果 u ′ 4 = 0000011000000110 u'^4=0000011000000110 u′4=0000011000000110则相应的计数器加1
  • T对明-密文尝试完毕后,真子密钥对应的计数器值最大
  • T越大,结果越准确

分析小结

  • 差分密码分析基于S盒不均匀的差分特征
  • 差分密码分析是一种不确定的明文分析方法,需要较多的明-密文对
    • 基于差分扩散率 ε \varepsilon ε的差分攻击想要获得成功,所需明-密文对数量T接近 c ε − 1 c\varepsilon^{-1} cε1(少于线性分析),c为某常数
    • 此算法只能分析最后一轮子密钥,缩小了穷举密钥的范围

高级加密标准

DES

  • 基于Feistel结构
  • 明文、密文、密钥长度为64位
  • 使用8个不同的非线性S盒
  • 使用扩展代换和压缩置换
  • 迭代16轮
  • 加密和解密算法相同,只是密钥编排方式不同

算法结构

输入明文(64位),首先进行预先初始置换IP,然后使用Feistel结构和16个子密钥进行16轮迭代。之后进行逆置换IP-1后输出密文

初始置换

将64位分为8个字节来看,置换后也是8×8。置换后每一个字节的最后一位属于初始的第一个字节,倒数第二位属于初始的第二个字节,……以此类推,置换后的8字节中每个字节的最后一个字节分别对应初始第一个字节的第2、4、6、8、1、3、5、7个字节。这个置换固定不变。

密钥编排过程

对于一个初始给定的密钥k,首先进行密钥置换 π k p \pi_{kp} πkp丢掉8比特(这8比特实际上作为校验位存在),对左28位进行循环左移ai位,对右28位循环右移a2位,其中当i=1,2,9,16时,ai=1,其他时候ai=2。然后进行压缩置换 π c p \pi_{cp} πcp再丢掉8比特,形成第一个轮密钥(48位)。

由上图可知,丢掉的是64位中每个字节的最后一位。

迭代过程

每一次迭代将输入的后32位与48位密钥进行函数处理得到32位与输入前32位异或得到输出的后32位,输出前32位即为输入后32位。


E为扩展置换:

S盒的代换方法:

每一组是6比特代换,里面最左边的一位和最右边的一位决定在哪一行代换,中间4位决定代换的值。如最左边为1,最右边为1,就应该在第4行找。S盒一共8个。

P为最终置换:

DES算法的安全性

所有的S盒都是固定的
IBM提交算法后,发现反馈的结果修改了所有的S盒
S盒的设计准则并未完全公开
怀疑算法存在“陷门”

S盒的设计准则

  • 每一行是整数0,…,15的一个置换
  • 没有一个S盒是输入变量的线性函数
  • 改变S盒的一个输入位至少要引起两位输出改变
  • 对于任何一个S盒和任意一个输入X,S(X)和S(X ⊕ \oplus 001100)至少有两个比特不同
  • 对于任何一个S盒,对于任何一个输入对e,f属于{0,1}4,S(X)≠S(X ⊕ \oplus 11ef00)
  • S盒的任意一位不变,其他5位变化时,输出中的0和1的总和基本相等

人们担心实际56比特的密钥长度不足以抵御穷举式攻击,密钥量只有越1017
DES算法基本没有发现其他重大的缺陷,线性攻击和差分攻击对计算复杂度有一定影响

DES存在4个弱密钥:使用弱密钥加密明文得到密文,对密文进行弱密钥加密和解密均可以恢复明文。( K 1 = K 16 K_1=K_{16} K1=K16
K 1 = 0101010101010101 K 2 = f e f e f e f e f e f e f e f e K 3 = 1 f 1 f 1 f 1 f 0 e 0 e 0 e 0 e K 4 = e 0 e 0 e 0 e 0 f 1 f 1 f 1 f 1 K_1=0101010101010101\\ K_2=fefefefefefefefe\\ K_3=1f1f1f1f0e0e0e0e\\ K_4=e0e0e0e0f1f1f1f1 K1=0101010101010101K2=fefefefefefefefeK3=1f1f1f1f0e0e0e0eK4=e0e0e0e0f1f1f1f1
半弱密钥:存在K和K’,使得 E K ⋅ E K ′ = I E_K\cdot E_{K'}=I EKEK=I,DES存在12个半弱密钥。
K 1 = e 001 e 001 f 101 f 101 , K 2 = 01 e 001 e 001 f 101 f 1 K_1=e001e001f101f101,K_2=01e001e001f101f1 K1=e001e001f101f101,K2=01e001e001f101f1
补密钥 D E S K ˉ ( M ˉ ) = D E S K ( M ) ‾ DES_{\bar{K}}(\bar{M})=\overline{DES_K(M)} DESKˉ(Mˉ)=DESK(M),补密钥将密钥的所有位取反得到。

DES不是幂等的,不能构成封闭群,因此可以通过自身乘积以提高安全性,其中三重DES使用最为广泛,使用不同密钥对其加密三次。

  • 中间相遇攻击双重DES:穷举密钥加密P1,保存结果,一共有256个值
  • 穷举前解密C1,比较P1加密的结果,若相同使用当前解密的密钥K2和表中对应的K1来加密P2,若得到C2,则说明得到正确的K1和K2,否则继续寻找。总复杂度为257,但空间使用也很大。

三重DES的工作方式:

  • DES-EEE3:三个不同密钥三次加密
  • DES-EDE3:三个不同密钥加密-解密-加密
  • DES-EEE2:两个不同密钥,K1=K3,加密3次
  • DES-EDE2:两个不同密钥,K1=K3,加密-解密-加密

AES

  • 比三重DES快

  • 至少与三重DES一样安全

  • 数据分组长度为128比特

  • 密钥长度为128/192/256比特

  • 可在全世界范围内免费得到

  • 采用SPN结构,加密和解密相似

  • 能够有效抵抗所有已知攻击

  • 没有发现弱密钥和补密钥

  • 结构简单,运算速度快

  • 支持128位分组,支持128/192/256位密钥

  • 轮数Nr依赖密钥长度,分别为10/12/14



字节代换

AES的S盒代换是基于有限域 F 2 8 = Z 2 [ x ] / ( x 8 + x 4 + x 3 + x + 1 ) \mathbb F_{2^8}=\mathbb Z_2[x]/(x^8+x^4+x^3+x+1) F28=Z2[x]/(x8+x4+x3+x+1)
a = a 7 a 6 a 5 a 4 a 3 a 2 a 1 a 0 a=a_7a_6a_5a_4a_3a_2a_1a_0 a=a7a6a5a4a3a2a1a0
∑ i = 0 7 a i x i \sum_{i=0}^7a_ix^i i=07aixi
字节代换: y = A x − 1 + c y=Ax^{-1}+c y=Ax1+c
A = ( 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 1 1 1 1 1 0 0 0 1 ) , c = ( 0 1 1 0 0 0 1 1 ) A=\begin{pmatrix} 1 & 1 & 1 & 1 & 1 & 0 & 0 & 0\\ 0 & 1 & 1 & 1 & 1 & 1 & 0 & 0\\ 0 & 0 & 1 & 1 & 1 & 1 & 1 & 0\\ 0 & 0 & 0 & 1 & 1 & 1 & 1 & 1\\ 1 & 0 & 0 & 0 & 1 & 1 & 1 & 1\\ 1 & 1 & 0 & 0 & 0 & 1 & 1 & 1\\ 1 & 1 & 1 & 0 & 0 & 0 & 1 & 1\\ 1 & 1 & 1 & 1 & 0 & 0 & 0 & 1 \end{pmatrix}, c=\begin{pmatrix}0\\1\\1\\0\\0\\0\\1\\1\end{pmatrix} A= 1000111111000111111000111111000111111000011111000011111000011111 ,c= 01100011
计算z=f(x)在有限域下的乘法逆元z-1,使用辗转相除法计算。

行移位变换

对状态矩阵每一行进行循环左移操作,第i行循环左移i-1个字节。(明文看做4*4字节的矩阵)

列混合变换


也就是和一个固定的矩阵相乘。

与轮密钥异或

与KNr异或即可。

AES密钥编排算法

若密钥长度为128字节,一共迭代10轮,需要11个轮密钥,每一个轮密钥为128位,密钥编排算法需要用128位主密钥key生成11个128位的轮密钥。
将4*4密钥矩阵中的每一列当做一个字,易知密钥编排算法需要输出44个字,表示11个轮密钥,AES密钥编排算法使用了S盒变换(与DES不同)

首先定义了10个常数:

初始密钥有4个字W[0],W[1],W[2],W[3],为第一次派生得来。之后的字的生成方式为:对于W[i],由于W[3]=(K12,K13,K14,K15)T,此时i=4,首先将第一字节与第四字节交换(K15,K12,K13,K14)T,然后逐字节进行代换。最后如果i整除4,就与上面的10个常数之一Rcon[i/4]异或(实际上只改了最高字节)。最后再与W[4-4]进行异或。一直计算到W[43]完成。
当列数不同时(密钥长度为192和256比特)时,代换与异或的判断条件有所改变。

SM4加密算法

  • 分组长度为128比特,密钥为128比特
  • 是对称加密算法,共需要32轮迭代,在解密算法中密钥逆序使用
  • 密钥扩展算法采用32轮迭代结构,与加密算法类似
  • 基于非均衡Feistel结构

每一轮迭代,产生32位新的比特序列,放在128位的最后面,前面的128位保留后96位放在前面,舍弃最前面的32位,类似于一个内部迭代过程。最后经过反序变换输出密文。
x 4 = x 0 ⊕ T ( x 1 ⊕ x 2 ⊕ x 3 ⊕ r k 0 ) x_4=x_0\oplus T(x_1\oplus x_2\oplus x_3\oplus rk_0) x4=x0T(x1x2x3rk0)

分组密码的工作模式

由基本密码、一些反馈和一些简单运算组合而成
每个密码标准在描述密码算法同时都定义相关工作模式

  • 电子密码本 ECB
  • 密码分组链接 CBC
  • 密码反馈 CFB
  • 输出反馈 OFB
  • 计数器模式 CTR

电子密码本模式——ECB

使用相同的密钥对每一块进行加密,对每一块加密后将每一块密文组合在一起即得到密文。
分组之间没有任何关系

优点:

  • 可以进行并行处理
  • 简单有效
  • 不存在错误传播问题。(加密产生的错误只会限制在一块之中)

缺点:

  • 相同明文分组会加密成相同密文分组
  • 对明文的主动攻击是可能的:可能会替换、重排、删除、重放信息块而改变原有明文的意义
  • 适合传输短信息(如加密口令)

密码分组链接模式——CBC

前一块明文的加密结果参与下一块的密文生成流程,看上去像是有链接关系。
分块之间相互影响:

  • 信息块不容易被替换、重排、删除、重放
  • 安全性好于ECB
  • 适合传输长度大于64位的报文
  • 是大多数系统的标准模式(SSL、IPSec等)

不足:

  • 没有已知的并行算法
  • 需要共同初始化向量IV
  • 存在错误传播现象,前面出错后面就全错了

密码反馈模式——CFB

将分组密码用于异步序列密码,数据可以在比分组小得多的单元里进行加密。
适用于实时加密字节级别的数据的情况

C 0 = I V (初始向量) C 1 = E k ( C 0 ) ⊕ P 1 C i + 1 = E k ( C i ) ⊕ P i P 1 = C 1 ⊕ E k ( C 0 ) P i = C i + 1 ⊕ E k ( C i ) C_0=IV(初始向量)\\ C_1=E_k(C_0)\oplus P_1\\ C_{i+1}=E_k(C_i)\oplus P_i\\ P_1=C_1\oplus E_k(C_0)\\ P_i=C_{i+1}\oplus E_k(C_i) C0=IV(初始向量)C1=Ek(C0)P1Ci+1=Ek(Ci)PiP1=C1Ek(C0)Pi=Ci+1Ek(Ci)

特点:

  • 没有已知的并行实现算法
  • 隐藏的明文模式
  • 需要共同的移位寄存器初始值IV
  • 存在错误传播(一个单元损坏影响多个单元)

输出反馈模式——OFB

将分组密码算法用于同步序列密码的方式
与CFB类似,不同的是进入移位寄存器的数据和被加密明文无关,只与初始向量无关。

特点:

  • 没有已知的并行实现算法
  • 需要共同的移位寄存器初始值IV
  • 不存在错误传播
  • 可以离线工作(离线生成密钥流,在线直接进行加密工作即可,相当于预处理过程)
  • 密钥序列最终会重复

计数器模式——CTR

引入一个计数器,使用密钥加密计数器的值,然后与明文异或。下一次加密将计数器加一相同操作。

  • 可以进行并行加密
  • 可以离线工作(预处理)
  • 吞吐量仅受可使用并行数量的限制
  • 加密数据块的随机访问
  • 可证明安全
  • 简单性(只要求实现加密算法)
  • 密钥只能使用一次,除非能维持很长的计数器

短块处理

通用方法:填充(padding)(当明文长度为分组长度的整数倍时,仍然需要添加一整个填充块)

  • pkcs#5/pkcs#7:最大分组长度为不小于8/256字节,缺失几个字节填充几遍填充字节数量

  • PKCS7填充法:FF FF FF FF FF FF FF FF FF 07 07 07 07 07 07 07

  • X923填充法:FF FF FF FF FF FF FF FF FF 00 00 00 00 00 00 07

  • ISO 10126填充:FF FF FF FF FF FF FF FF FF 7D 2A 75 EF F8 EF 07

  • 一种特殊方法

  • 自主指定,None,Zeros

  • 避免使用padding造成数据长度的扩充CTS(CipherText Stealing,密文挪用)

  • 工作模式安全性依赖于算法本身的安全性

  • 常用工作模式的比较:分组密码算法的作用、随机数的不可预测性、计数器的新鲜性、并行性、错误传播

  • 短块处理:填充、密文挪用

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: AES(Advanced Encryption Standard)是一种常用的分组密码算法,它支持128、192和256位的密钥长度。AES算法是由美国国家标准与技术研究院(NIST)于2001年发布的,并且已经被广泛应用在各个领域中。 在进行AES加密操作前,首先需要确定密钥的长度,并通过密钥扩展算法生成相关的轮密钥。轮密钥是通过对原始密钥进行一系列运算,产生多个轮次的中间结果得到的。 在加密操作中,AES算法将明文分为多个长度为128位(16字节)的数据块,并通过多轮的混淆和替代操作,将每个数据块转换为密文数据块。这其中包括4个阶段的处理:字节代换、行移位、列混淆和轮密钥加。 在解密操作中,AES算法将密文数据块通过逆向处理,逐步还原为明文数据块。解密过程包括4个阶段的处理:逆字节代换、逆行移位、逆列混淆和逆轮密钥加。 AES算法的加密解密操作是可逆的,即通过正确的密钥和操作步骤,可以将密文还原为明文或者将明文转换为密文。 总之,AES算法是一种高效且安全的分组密码算法,它通过多次迭代的混淆和替代操作,对输入数据进行加密操作。通过正确的密钥和步骤,可以将密文还原为明文,或者将明文转换为密文。这种算法被广泛应用于数据加密和保护隐私信息的场景中。 ### 回答2: AES(高级加密标准)是一种分组密码算法,用于加密和解密操作。它是一种对称密钥算法,意味着使用相同的密钥进行加密和解密。 AES算法使用一个称为"轮"的重复过程,通过多次迭代的代换和置换操作来加密和解密数据。它支持三个不同的密钥长度:128位、192位和256位。 在使用AES算法进行加密时,明文被分成相同长度的块,每个块都会经过一系列的替代、置换、混淆等操作。然后,使用加密密钥对每个块进行处理,这个密钥必须是与解密操作使用的密钥相同。最后得到密文。 在解密操作中,使用相同的密钥对密文进行处理,逆转替代、置换、混淆等操作,然后得到原始的明文。 C语言可以用来实现AES加密解密操作。通常,需要引入一个密码库,如OpenSSL,以便使用其中的AES函数库。可以通过定义并初始化密钥、明文、密文等变量,然后使用AES加密函数来进行加密,使用AES解密函数来进行解密。 需要注意的是,在使用AES加密解密操作时,密钥的安全性至关重要。密钥必须安全保存,以防止被未经授权的人访问。 总之,AES是一种分组密码算法,用于加密和解密操作。通过使用C语言中的密码库,可以实现AES加密解密操作。但在使用时,需注意密钥的安全性。 ### 回答3: AES(Advanced Encryption Standard)是一种常见的对称分组密码算法,被广泛应用于数据加密和保护的领域中。 AES加密解密操作C使用C语言编写,通过调用相应的AES算法库来实现加密和解密的过程。下面将以C语言为例,使用AES算法库进行AES加密和解密的操作。 首先,需要在C语言代码中引入相关的AES库文件,声明相应的函数和变量。然后创建密钥和待加密的明文数据,并设置相应的加密模式和填充模式。接下来,使用AES算法库提供的函数,将明文数据与密钥进行加密操作。最后将得到的密文数据进行输出。 示例代码如下: ``` #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/aes.h> void encryptAES(char *key, char *plainText, unsigned char *ciphertext){ AES_KEY aesKey; if (AES_set_encrypt_key((unsigned char *)key, 128, &aesKey) < 0) { fprintf(stderr, "Unable to set encryption key in AES\n"); exit(1); } AES_encrypt((unsigned char *)plainText, ciphertext, &aesKey); } void decryptAES(char *key, unsigned char *ciphertext, char *deciphertext){ AES_KEY aesKey; if (AES_set_decrypt_key((unsigned char *)key, 128, &aesKey) < 0) { fprintf(stderr, "Unable to set decryption key in AES\n"); exit(1); } AES_decrypt(ciphertext, (unsigned char *)deciphertext, &aesKey); } int main(){ char key[] = "0123456789abcdef"; char plainText[] = "Hello,AES!"; unsigned char ciphertext[AES_BLOCK_SIZE]; char deciphertext[AES_BLOCK_SIZE]; encryptAES(key, plainText, ciphertext); printf("Ciphertext: "); for(int i=0; i<AES_BLOCK_SIZE; i++){ printf("%02x", ciphertext[i]); } printf("\n"); decryptAES(key, ciphertext, deciphertext); printf("Deciphertext: %s\n", deciphertext); return 0; } ``` 以上示例代码实现了AES加密和解密的操作,并输出了加密后的密文和解密后的明文。其中使用的密钥为"0123456789abcdef",待加密的明文为"Hello,AES!"。 这就是一个简单的使用C语言进行AES加密解密操作的实例。当然,在实际应用中,我们还需要考虑更多的安全性和实用性考量,例如密钥的生成与管理、数据分块处理等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值