AES

5 阅读4分钟

简介

AES是一种对称加密方式(加解密双方使用一把密钥),采用固定S盒和多轮变换的方式,具有混淆和扩散特性的加密算法

组成

密钥

固定支持128,192,256位密钥长度.分别对应10,12,14轮加密

分组

将明文分割为128位固定块,逐块处理,支持ECB、CBC等多种模式;

多轮变换

状态(中间结果)

类似明文分组和密文分组,算法的中间结果的分组 为 状态,所有的操作都在状态上进行.

状态可以用一字节伪元素的矩阵阵列表示

该阵列为4列,列数记为 Nb, Nb等于分组长度除以32.本质上是一个二维字节数据

AES算法中,明文和密文都被划分为固定大小的块,而状态就用于存储这些数据块,在加密和解密各个阶段的中间结果

结构: 通常状态是一个4xN字节的矩阵,这里的N取决于分组长度

种子秘钥类似的使用一个字节为元素的矩阵阵列表示

种子密钥

用户提供的初始密钥,它是AES加密和解密的基础.种子密钥的长度可以是128,192和256位

种子密钥本身并不直接用于每一轮的加密操作,而是通过密钥扩展算法生成一系列轮秘钥.

密钥扩展算法会根据种子密钥生成足够数量的轮密钥,这些轮秘钥会在不同的加密轮次中使用.每一轮的秘钥长度和分组长度相同,都是128

示例

用户选择了一个128位的种子密钥,那么加密过程中,密钥扩展算法会基于这个种子密钥生成11个128位的轮密钥,其中一个用于初始轮,另外10个分别用于后续的10轮加密操作

轮数

指AES加密过程中进行的迭代次数.AES算法的加密过程由多个轮次组成,每一轮都会对状态进行一系列的变换操作,从而逐步增强加密的安全性

轮数的确定

分组长度(位)种子密钥长度(位)轮数
12812810
12819212
12825614
19219212
19225614
25625614

增加轮次可以增强加密的安全性,因为更多的轮次意味着更多的变换操作,使得攻击者更难通过分析密文来破解密钥.但是同时,轮次的增加也会导致加密和解密的计算量增大,降低算法效率.

有限域

又称伽罗瓦域(为了纪念埃瓦里斯特.伽罗瓦命名)是包含有限个元素的域.GF(q)

和其他域一样,有限域是进行加减乘除运算都有定义并且满足特定的规则(白马非马,加减乘除非加减乘除)的集合.

有限域最常见的例子是当p为素数时,整数对p取模.

有限域的元素个数称为他的阶

定理

  • 有限域的阶(有限域中元素的个数)是一个素数的幂
  • 对于每个素数p和每个正整数n在同构的意义下存在唯一的pnp^n阶的有限域,并且所有元素都是方程 xpnx=0x^{p^n} -x =0的根,该域的特征为p
  • 有限域的乘法群是循环群.即若F是有限域,则存在 αF使得F=xFx0=αα∈F使得F∗={x∈F|x≠0}=⟨α⟩。
  • 有限域是完美域,即他的任意代数扩张一定是可分扩张
  • 有限域的有限扩张一定是伽罗瓦扩张,并且对应的伽罗瓦群是循环群

在抽象代数中,域是一种具有加法和乘法的集合,且其加法和乘法运算如同普通的有理数还是实数.

四则运算的加减乘除适用于无限域(有理数域,实数域)

域的运算规则不依赖常规整数的"数值大小",而是通过多项式模运算定义

GF(28)GF(2^8)

加法规则

多项式的加法是模加法(对应系数异或,因为模2) 例如

字节b7b6b5b4b3b2b1b0(bi∈{0,1})对应多项式b7x7+b6x6+b5x5+b4x4+b3x3+b2x2+b1x+b0b7x7+b6x6+b5x5+b4x4+b3x3+b2x2+b1x+b0。

字节0x57(二进制01010111)对应多项式: x6+x4+x2+x+1x6+x4+x2+x+1

字节0x83(二进制10000011)对应多项式: x7+x+1x7+x+1

乘法规则

GF(28)GF(2^8)的乘法本质是多项式的模乘,需遵循以下步骤:

乘法需模一个8次不可约多项式(即无法分解为更低次多项式乘积的多项式),AES标准中选择的不可约多项式为:

m(x)=x8+x4+x3+x+1m(x)=x8+x4+x3+x+1

其16进制表示为0x11B(二进制100011011)

运算步骤

对于两个元素a(x)和b(x),其乘积为

c(x)=a(x)b(x)modm(x)c(x) = a(x)*b(x) mod m(x)

加密过程

AES是一种分组密码算,他将明文数据分成固定长度的块,然后对每个块进行加密处理.

加密过程主要包括以下几个步骤:

  1. 密钥的扩展

目的

根据输入的种子密钥生成多个轮密钥,每一轮加密都使用不同的轮密钥.轮密钥的数量由密钥长度决定.128->10轮,需11个轮密钥;192->12轮,需要13个密钥;256->14轮,需15个轮密钥

过程

将种子密钥按字节存储在一个数组里

以四个字节为一个字word,将密钥数组划分为若干字

通过一系列变化,包括字节代换,循环位移和轮常量异或等操作,从种子密钥生成所有轮密钥

  1. 初始轮

目的

将明文块与第一轮轮密钥进行异或操作,为后续的加密轮次做准备

过程
  • 将128位的明文按字节存储到一个 4x4的状态矩阵中
  • 第一轮轮密钥也按照字节排列成4x4的矩阵
  • 对状态矩阵和轮密钥矩阵的对应元素进行异或运算,得到初始轮候的状态矩阵

示例

明文128位 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff填充后的状态矩阵为:

列0 列1 列2 列3
00 44 88 cc
11 55 99 dd
22 66 aa ee
33 77 bb ff

3. 多轮加密

除了初始轮和最后一轮,中间的每一轮都包括这四个基本操作

1. 字节代换

 目的: 使用一个固定的S盒对每个字节进行非线性替换,增强加密的混淆性

过程: 使用一个固定的S盒(substitution box),将状态矩阵中的每个字节替换为S盒中对应位置的值

  • 代换表(即S盒)是可逆的,由以下两个变换的合成得到的
  • 首先,将字节看做GF(28)GF(2 ^ 8)上的元素,映射到自己的乘法逆元, '00' 映射到自己
  • 其次,对字节做如下的GF(2)GF(2)上的,可逆的)仿射变换 1. 上述S盒对状态的所有字节所得的变换记为: ByteSub(State)  ByteSub的逆变换由代换表的逆表做字节代换,可通过如下两步实现,首先惊醒仿射变换的逆变换,再求每一个字节在GF(2^8)上的逆元
2.行位移

对状态矩阵的行进行循环唯一,增加数据的扩散性 过程:

  • 将状态矩阵的第0行保持不变,第一行循环左移1个字节,第二行循环左移2个字节,第三行循环左移3个字节
  • 行位移是将状态阵列的各行进行循环位移,不同行的位移量不同 0->0,1->1,2->2,3-3.
  • 位移量的取值和Nb有关 1. 按照指定的位移量对状态的行进行位移 : ShiftRow(state) 1. shiftRow的逆变换是对状态阵列的后三列分别以位移量Nb-C1,Nb-C2,Nb-C3进行循环唯一,使得第i行第j列的字节位移到(j+Nb-Ci) mod Nb
3. 列混合

对状态矩阵的列进行线性变换,进一步扩散数据

过程: 将状态矩阵的每一列视为一个多项式,与一个固定的多项式进行模运算,得到新列

  • 列混合变换中,将状态阵列的每列视为 GF(2^8)上的多项式,再与一个固定的多项式c(x)进行模(x^4+1)乘法.要求c(x)是模(x^4+1)的可逆多项式,否则列混合变换就是不可逆的.因此回事不同的输入分组对应的输出分组可能相同.
  • Rijndael的设计者给出的c(x)为 c(x)=03x3+01x2+01x+02c(x) = '03'x^3+'01'x^2+'01'x+'02'
  • 为什么选择模(x^4+1)后续证明
  • c(x)是与x^4+1 互素的,因此模x^4+1是可逆的.列混合算法也可以写为矩阵乘法.设 b(x) = c(x)*a(x),则 1.
  • 这个运算需要做GF(2^8)上的乘法,但是由于所乘的因子是三个固定的元素02,03,01,所以这些乘法运算还是比较简单的
  •  对状态的所有列所做的列混合运算记为 1.
  • 列混合运算的逆运算类似.每一列都用一个特定的多项式d(x)相乘.d(x)满足

c(x)=03x3+01x2+01x+02c(x)=03x3+01x2+01x+02 的在GF(28)下模x4+1GF(2^8)下 模x^4 +1乘法逆元 d(x)=0Bx3+0Dx2+09x+0Ed(x) = 0Bx^3 +0Dx^2+09x+0E c(x)d(x)1mod(x4+1)c(x)⋅d(x)≡1mod(x^4+1))

4.轮密钥加

将状态矩阵与当前轮的轮密钥进行异或操作

目的:将之前轮状态矩阵与该轮的轮密钥进行异或操作,引入秘钥信息

过程: 将状态矩阵和轮密钥矩阵的对应元素进行异或运算

  • 密钥加是将轮密钥简单地与状态进行逐bit异或.轮密钥由种子秘钥通过密钥编排算法得到,轮密钥长度等于分组长度Nb.

  • 状态state与轮密钥roundKey的秘钥加运算表示为AddRoundKey(state, roundkey)

  1. 最后一轮

最后一轮的操作和中间轮基本相同,但是不进行列混合操作,只包含字节代换,行位移,轮密钥加三个步骤

解密过程

  1. 密钥扩展

这一步和加密过程中的密钥扩展完全相同.依据输入的种子密钥,借助密钥扩展算法生成一系列轮密钥.

轮密钥的数量由密钥长度决定 128->10, 192->13, 256->15

  1. 初始轮

把密文块与最后一轮的轮密钥进行异或操作,为后续轮次解密做准备

过程:

  • 将128位的密文按照字节存储于一个4x4的矩阵中
  • 把最后一轮的秘钥也按照字节排列成4x4的矩阵
  • 对状态矩阵和轮密钥矩阵对应元素做异或运算,得到初始轮候的状态矩阵
  1. 多轮解密

    1.   逆字节代换

      目的: 对状态矩阵中的每个字节执行与加密时字节代换相反的操作,恢复字节的原始值

      过程: 使用一个固定的逆S盒(与加密时的S盒对应),把状态矩阵中的每个字节替换为逆S盒中对应位置的值

    1.   逆行位移

      目的: 对状态矩阵的行进行与加密时行位移相反的循环移位操作,恢复行的原始顺序

      过程: 将状态矩阵的第0行保持不变,第1行右移1个字节,第二行循环右移2个字节,第三行循环右移3个字节

    1.   逆列混合

          目的: 对状态矩阵的列进行与加密时列混合相反的线性变换,恢复列的原始值

          过程: 把状态矩阵的每一列视为一个多项式,与一个固定的你多项式进行模运算,得到新的列

    1.   轮密钥加

          目的: 将当前的状态矩阵与该轮的轮密钥进行异或操作,引入密钥信息

          过程: 对状态矩阵和轮密钥矩阵的对应元素进行异或运算

  1. 最后一轮

最后一轮和中间轮的操作基本相同,但不进行逆列混合

加密模式

ECB

Electronic code book电码本模式

将整个明文分成若干个相同的小段,然后对每一个小段进行加密

每组的大小和密钥长度相同

优点

  1. 有利于并行计算
  2. 误差不会被传送

缺点

  1. 安全性低--相同的明文块会生成相同的密文,容易暴露明文规律
  2. 可能对明文进行主动攻击

适合加密小消息

CBC

Cipher block chaining 密码分组链接

第一块与初始化向量(IV,随机128位值)异或,再用密钥加密

将整个明文分成若干个相同的小段,然后每一个小段与上一段的密文端进行异或运算后,再与密钥进行加密

  1. 不容易主动攻击,安全性好于ECB,适合长度长的报文,是SSL,IPSec的标准

缺点

  1. 不利于并行计算

  2. 误差传递

  3. 需要初始化向量IV

CTR

Counter 计算器模式

  1. 在ctr模式中有一个自增的算子

  2. 算子用密钥加密后的输出和明文异或的结果得到密文

  3. 简单快捷安全可靠,而且可以并行加密

  4. 但是在计算器不能维持很长的情况下,密钥只能使用一次

CFB

密码反馈模式

  1. 隐藏了明文
  2. 分组密码转化为流模式
  3. 可以及时加密传送小于分组的数据

缺点

  1. 不利于并行计算

  2. 误差传送

  3. 唯一的IV

OFB

输出反馈模式

  1. 隐藏了明文
  2. 分组密码转化为流模式
  3. 可以及时加密传送小于分组的数据

缺点

  1. 不利于并行计算

  2. 明文攻击

  3. 误差传送

安全性

替换-置换网络(SPN)非线性变换(字节代换)与线性扩散(行位移,列混合).实现混淆和扩散的密码学原则,有效抵抗差分攻击,线性攻击等常见密码分析方法

轮密钥的强随机性

可逆性

S盒逆S盒 映射可逆

列混合的依靠有限域的乘法逆元

轮密钥的2次异或 还原数据

GF(2^8) 在模x^4 +1 下的乘法逆元

AES选取了一组

c(x)=03x3+01x2+01x+02c(x)=03x3+01x2+01x+02 的在GF(28)下模x4+1GF(2^8)下 模x^4 +1乘法逆元

d(x)=0Bx3+0Dx2+09x+0Ed(x) = 0Bx^3 +0Dx^2+09x+0E

c(x)d(x)1mod(x4+1)c(x)⋅d(x)≡1mod(x^4+1))

Q&A

问:

为什么要做行位移,列混合

答 为了扩散,提高加密安全

问: AES 行位移是固定的,那它存在的意义是什么

答 其核心意义在于将输入数据的单个字节变化扩散到整个状态矩阵,从而增强加密算法的安全性

问: 为什么加密过程和解密过程的步骤都是字节代换 行位移 列混合 轮密钥加 ?不应该是加密时1234步骤,解密时4321步骤么

答: 加密和解密的所有操作都是基于字节数据的.

1.字节代换的S盒和逆S盒 (不会影响到数据)不会改变数据本身.操作单元不会改变

2.行位移相当于移动数据位置,列混合则是通过乘法逆元配合多项式实现混淆,但是可逆.操作单元针对一对乘法逆元的模乘后还是本身

3.轮密钥的使用是反向的,但是 在操作过程中轮密钥会对 矩阵数据产生影响,所以要放到最后

4.同时初始轮和最后一轮 不做列混合也是为了保证轮密钥加的结果