在学习AES算法之前,最先清楚地应当是七大加密模式,这七大加密模式下的AES加密有着天壤之别,因此本文将从AES的7大加密模式开始探究逐步挖掘AES算法
一、七大加密模式
1.ECB:Electronic Codebook,电子密码本模式
原理
每个分组独立(以下均先以AES-128来展开)
加密:
解密:
特点
- 不需要 IV
- 相同明文块,在相同密钥下会得到相同密文块
- 可以并行加密、并行解密
- 实现最简单
是否需要 padding
需要。因为它是按块处理的。如果明文长度不是块大小整数倍,就要 padding;除非你明确用 NoPadding 且数据本来就是整块对齐。
2.CBC:Cipher Block Chaining,密码块链接模式
每一块明文在加密前,先和前一个密文块异或。第一块使用 IV:
解密:
特点
- 需要 IV
- 即使两个明文块相同,只要前面的链不同,密文通常也不同
- 解决了 ECB 的“重复块泄露”问题
- 加密是串行的,不能天然并行
- 解密可并行(因为每块只依赖当前密文块和前一密文块)
IV 要求
CBC 的 IV 一般要求:
- 长度等于块大小
- 不可预测 / 随机
- 同一密钥下最好不要重复
是否需要 padding
需要。
3.CTR:Counter,计数器模式
原理
CTR 把分组密码变成“密钥流生成器”
先对 nonce + counter 加密,得到一个密钥流块:
然后与明文异或:
解密同样也是异或:
特点
- 不需要 padding
- 可以随机访问某个块
- 加密解密都可并行
- 性能高,工程上很常用
4.GCM:Galois/Counter Mode,伽罗瓦/计数器模式
原理
GCM = CTR 加密 + GHASH 认证
它一边用 CTR 产生密钥流加密消息,一边对:
- AAD(附加认证数据,不加密)
- 密文
做一个 GF(2^128) 上的认证计算,最后得到 tag。
输出一般是:
- ciphertext
- authentication tag
AAD 是什么
AAD 是“要认证但不加密”的数据,比如:
- 协议头
- 长度字段
- 序号
- 元数据
特点
- 既保密,又防篡改
- 可并行
- 高性能
- 现代协议里极其常见(TLS、IPsec 等)
5.CCM:Counter with CBC-MAC,计数器与 CBC-MAC 模式
原理
CCM = CTR 加密 + CBC-MAC 认证
和 GCM 一样,也是 AEAD,只是认证部分不是 GHASH,而是 CBC-MAC。
6.OFB:Output Feedback,输出反馈模式
原理
先用 IV 经加密器产生输出,再把这个输出继续送回加密器,形成密钥流:
然后:
解密同样:
特点
- 不需要 padding
- 本质上把分组密码变成同步流密码
- 某个密文 bit 出错,只会影响解密后对应那一 bit
- 不会像 CBC 那样大面积传播
7.CFB:Cipher Feedback,密码反馈模式
原理
把“前一个密文块”送进加密器,输出后与当前明文异或:
首块:C1=P1⊕EK(IV)
后续:Ci=Pi⊕EK(Ci−1)
解密时:P1=C1⊕EK(IV) Pi=Ci⊕EK(Ci−1)
特点
- 不需要 padding
- 可以按字节/按位工作,也可以按整块工作
- 自同步:丢了一些数据后,经过若干反馈长度后有机会重新同步
- 加密通常串行
二、AES详解
AES对称加密算法的地位:被美国国家标准与技术研究院于2001年正式采纳为联邦信息处理标准。
1、AES算法概述
AES是一种对称加密算法,数据被分割成固定大小的块(128位|16字节)进行加密,AES支持三种密钥长度,分别对应128、192、256。
2.AES加密原理
AES加密总体步骤
AES算法采用多轮变换操作实现加密,每轮都包含四个基本步骤:
1、字节替换:通过S盒实现非线性字节替换
2、行移位:对状态矩阵进行循环移位
3、列混淆:对列进行线性变换
4、轮密钥加:与轮密钥进行异或运算
我们可以发现AES几乎集成了传统加密方式的所有变换特点,因此其加密的复杂性也相对较高
AES的常见数据规格
AES-128:密钥长度128、分组长度128、轮数10
AES-192:秘钥长度192、分组长度128、轮数12
AES-256:密钥长度256、分组长度128、轮数14
对应关系通常记成:
Nb = 4,表示状态矩阵有 4 列(固定) #Nb = BlockSize / 32 = 128 / 32 = 4Nk = 4/6/8,对应密钥字数(1字表示32字节) #Nk = KeySize / 32Nr = 10/12/14,对应轮数 #Nr由密钥长度决定
分块
AES一次处理16字节输入块,这16字节输入块会被排成4*4的状态矩阵state
如果明文块是:
AES 内部通常按列填充为:
AES整体加密流程
AES不是一上来就循环加密,而是先进行初始轮密钥加、中间若干轮、最后一轮
下面以AES-128为例展开(以下名词分别对应前面写的4大步骤)
1)先执行一次AddRoundKey
2)前 9 轮
每轮执行:
SubBytes
ShiftRows
MixColumns
AddRoundKey
3)最后一轮
执行:
- SubBytes
- ShiftRows
- AddRoundKey
注意:
最后一轮没有 MixColumns。
AES四大核心变换详解
1.AddRoundKey(轮密钥加)
把当前状态矩阵 State 与该轮的轮密钥逐字节异或:
2.SubBytes(字节代换)
它会对 State 中的每个字节单独替换:
这个 S-box 不是随便查表,而是两步构造出来的:
第一步:在 GF(2^8) 中求乘法逆
把每个字节看成有限域 GF(2^8) 上的元素。
除了 0 以外,每个元素都取乘法逆元;0 特判为 0。
有限域使用的不可约多项式是:
它对应十六进制 0x11B。
第二步:做仿射变换
对逆元结果再进行一次线性/仿射变换,得到最终 S-box 输出。
所以 AES 的 S-box 不是任意常量表,而是有明确代数结构。
3.ShiftRows(行移位)
这一步对 State 的每一行做循环左移:
- 第 0 行:不移
- 第 1 行:左移 1 字节
- 第 2 行:左移 2 字节
- 第 3 行:左移 3 字节
4.MixColumns(列混合)
对 State 的每一列,都把 4 个字节当成一个向量,然后与固定矩阵相乘:
乘法和加法都不是普通整数运算,而是在 GF(2^8) 中进行:
- 加法 = XOR
- 乘法 = 有限域乘法
三、AES 解密过程
AES 解密不是“把加密倒着写一下”那么简单,但思路就是对每步做逆运算,这边不做详细阐述了
对应四个逆变换:
- InvSubBytes
- InvShiftRows
- InvMixColumns
- AddRoundKey(异或自己就是逆)
解密大致流程是:
- 先加最后一轮轮密钥
- 做若干轮逆变换
- 最后一轮不做 InvMixColumns
逆矩阵对应为:
这也是在 GF(2^8) 上运算。
四、AES 的密钥扩展(Key Schedule)
AES 不是每轮都直接拿原始密钥来异或,它会先把主密钥扩展成多个 轮密钥。
1.AES-128 密钥扩展核心操作
设原始密钥分成 4 个 word:
后面逐步生成:
规则大致是:
- 若
i mod Nk != 0,则 #Nk是前面说的key的字数(32bit为一字,放在128里Nk==4)
- 若
i mod Nk = 0,则
其中函数 g() 包括:
- RotWord:循环左移 1 字节
- SubWord:每字节过 S-box
- Rcon:与轮常量异或
RotWord
例如:
SubWord
把 4 个字节分别经过 AES S-box 替换。
Rcon
轮常量一般写成:
- 01 00 00 00
- 02 00 00 00
- 04 00 00 00
- 08 00 00 00
- 10 00 00 00
- ...
本质是有限域中的幂递推。
AES-256 的密钥扩展稍复杂
AES-256 中:
Nk = 8- 某些位置除了
g()外,还会额外做一次SubWord
所以 AES-256 的 key schedule 和 AES-128 并不只是“多几轮”那么简单。
五、总结
AES负责将16字节明文进行加密,而加密模式负责把输入的内容(任意长度)拆成多组16字节的内容再进行加密,实现AES加密的连续性。本人目前尚未见过对于AES算法的魔改题目,因此,做 CTF 逆向和应急,AES 最重要的不是“背算法”,而是知道什么时候它是标准实现、什么时候它被错误使用、什么时候它被故意改坏,以及你该从哪里把 key 和模式证据挖出来。
Comments NOTHING