给现代密码学讲课准备的文档……
The AES Block Cipher
概述
AES | 密钥长度(bit) | 分组长度(bit) | 加密轮数 |
---|---|---|---|
AES-128 | 128 | 128 | 10 |
AES-192 | 192 | 128 | 12 |
AES-256 | 256 | 128 | 14 |
以下均以AES-128说明
16字节 -> 4*4矩阵
1.轮密钥加
2.AES encrypt
3.重复2若干轮
4.Last AES encrypt
详述
轮密钥加(AddRoundKey)
明文与轮密钥异或
AES encrypt
1 | SubBytes(state); //字节替换 |
字节替换
AES定义了一个S盒和一个逆S盒(16*16的表)。
字节替换是将矩阵中每个字符在S盒中的映射进行替换,即一个简单的查表操作。
映射方法:把该字节的高4位作为行值,低4位作为列值,取出S盒中对应的行的元素作为输出。
解密时从逆S盒取出元素。
state = aes_sbox[state >> 4][state & 0x0F];
行移位
第i行循环左移i字节。
列混合
每一列乘以一个固定的矩阵,得到新的一列密文
其中,矩阵元素的乘法和加法都是定义在基于
矩阵中的第j列(0≤j≤3)的列混合可以表示为下图所示:
逆运算只需要乘原矩阵的逆矩阵即可。
轮密钥加
与轮密钥异或
Last AES encrypt
进行字节替换、行移位、轮密钥加(不必进行列混合)
重复若干轮
1 | //aes_encrypt() |
应用
代码量 or 速度?
- 节约代码量
如果不预先计算(S盒等大量数据),可以获得代码量最小的AES实现。但此时速度最慢。 - 提高速度
通过预先计算(S盒等大量数据)来提高运行速度。但此时代码量会稍微增大。
通过预先计算轮函数(使整个AES加密变成一个查表和异或的过程)来大大提高运行速度。但此时代码量会大大增大。
总而言之,AES总能在代码量和性能之间找到一个平衡点。
硬件支持
使用128bit的寄存器(对应AES加密块的位数) -> 14倍加速
1 | /* |
安全性
还原密钥
AES的密钥只有126位,对这126bit进行穷举。
显然这不会伤害AES的安全性。
对AES-256的相关密钥攻击
AES-256的密钥扩展设计上有弱点,针对此可以进行相关密钥攻击。
如果有大约
显然这仍不足以伤害AES的安全性。
Block Ciphers From PRGs
我们能否从一个PRG构建一个PRF?
构建PRF
PRG:伪随机数发生器(输出与真随机序列不可区分)
PRF:伪随机函数
设
定义
输入为1bit的值,输出为0或1任一个值。
输入为0时,用左边的输出(),输入为1用右边的输出。
如果G是一个安全的PRG,那么F是一个安全的PRF。显然这是一句废话
扩展PRG
得到一个 2bit 的 PRF:
如何证明
如何证明这个四元组输出与随机序列不可区分?
- 我们知道发生器G是安全的,因此第一层的输出与随机序列不可区分。换句话说,我们可以用真随机字符串来替换第一层。因此,我们从密钥空间中随机选取
和 来替代 和 。容易知道这两个分布是安全的,即没有有效的攻击可以区分这两个分布。如果存在这样的攻击,就说明G是不安全的,那么与PRG的定义矛盾。 - 现在我们要对左边做同样的事情。换句话说,继续用真随机替
和 换左下角两个伪随机输出。这跟第1步一样,因为G是安全的,所以我们可以进行这样的替换。 - 最后再对右边进行一次真随机的替换,我们就得到了一个真随机的四元组输出。
再次扩展
可以扩展3次,就可以扩展n次。
GGM PRF
GGM是这个PRF的3位发明者的首字母缩写
容易证明:G是一个安全的PRG
不过此函数在实际应用中并不多,因为它的速度太慢了。产生
bit输出需要运行发生器n次。
能否从一个安全的PRG构建一个安全的分组密码 or 能否从一个安全的PRG构建一个安全的PRP?
PRP:伪随机置换
- 不能。
- 可以,只要将GGM PRF应用Luby-Rackoff构造法(一个3轮的Feistel网络)即可。
- 这取决于PRG的实现。
PRG
PRF Luby-Rackoff(3轮Feistel) PRP
引用到的数据
1 | static const BYTE aes_sbox[16][16] = { |
1 | static const BYTE aes_invsbox[16][16] = { |
作业题
作业题跟正文无关
题目描述
1、 AES加密模式为CBC,初始化矢量即IV为零,填充为01-00)。此外,相应的密钥在身份证件上的机器可读区域(MRZ)等表格中,它与欧洲的电子护照一起使用时并不十分完整。
2、 目标是找到以下base64编码消息的明文:9MgYwmuPrjiecPMx61O6zIuy3MtIXQQ0E59T3xB6u0Gyf1gYs2i3K9Jxaa0zj4gTMazJuApwd6+jdyeI5iGHvhQyDHGVlAuYTgJrbFDrfB22Fpil2NfNnWFBTXyf7SDI
3、 对于加密,已生成并应用基于基本访问控制(BAC)协议的密钥KENC。对于解密,已经发送了以下字符,从中可以导出KENC(这些字符的编码类型在[1]中描述): 12345678 <8 <<< 1110182 <111116?<<<<<<<<<<<<<<< 4
4、 在传输过程中丢失了并且突出显示了一个’’?’’。可以在[2]的帮助下恢复它。
为了能够在之后计算密钥KENC,可以找到应用编码的概述
[3],[4]中的协议和[5]中的一个例子。
5、 在解密之前解码base64代码。
解题步骤
求未知数字
![](/img/code/pht/cry1.png width=100% />
按照给出的步骤手搓脚本即可求出未知数
计算key
Kseed
对数字和校验位sha1后取[:16]
即可。
Ka Kb
Kseed+c然后sha1,ka是[:16]
,kb是[16:32]
key
对ka和kb奇偶校验即可
解密
1 | from Crypto.Cipher import AES |
感想
感觉算是……解决了现实生活中的一个问题?hhhhhhhhhhhhhh
关于本文
本文作者 云之君, 许可由 CC BY-NC 4.0.