Title: Fish Magic
Creator: Paul Klee, Swiss, 1879 - 1940
Creator Nationality: Swiss
Creator Gender: Male
Creator Death Place: Muralto, Switzerland
Creator Birth Place: Münchenbuchsee, Switzerland
Date: 1925
Physical Dimensions: w38.75 x h30.39 in (Overall)
Type: Paintings
Rights: © 2014 Philadelphia Museum of Art. All rights reserved
Medium: Oil and watercolor on canvas on panel
进入web3以来,越来越感受到密码学的重要性,尤其是开始研究zkp以后,更是如此。知识,亦是常学常新,在经过了zkp的洗礼之后,重新再来看基础密码学,也有颇多新解
本篇内容主要取材于Dr Lynndell的密码学讲座,不同于图解密码系列,而是更加深入的研究对称密码和AES算法
核心原理
对称加密与哈希函数的核心原理:实现随机性
常见的实现方式主要包括三大变换:
-
线性变换:每 bit 的输入发生变换,影响 50%输出,密文随机性高
-
非线性变换: S-box (substitution-box),抵抗解方程组攻击、延展攻击
-
轮密钥加/轮常量加:添加一些随机密钥或常量,提高信息商
对称加密
统一描述
形式化描述:
初始化:双方共享一个保密随机数K ,或使用相同的设备生成一个相同的随机数K
加密:发送方使用设备生成随机数K ,对消息X ,如下计算
$
Y := K \oplus X
$
发送密文Y
解密:接收方接收密文Y ,使用设备生成随机数K ,如下计算
$
X := K \oplus X
$
获得消息X
AES
在前文《图解密码技术》读书笔记(1)——对称密码与分组密码中已经初步介绍过AES的概念,这里主要详解介绍下其具体的加密过程、最重要的轮函数原理以及密钥扩展的算法
AES 具体来说是一种加密标准,最终入选的具体算法是由比利时两位著名的密码学家 Joan Daemen 和 Vincent Rijmen设计的Rijndael算法
Rijndael是一个分组密码算法族,其分组长度包括128比特、160比特、192比特、224比特、256比特,密钥长度也包括这五种长度,但是最终AES只选取了分组长度为128比特,密钥长度为128比特、192比特和256比特的三个版本
下图展示了AES的算法流程:
从图中可以看出,算法最关键的部分就是轮函数的运算和轮密钥的生成
轮函数
轮函数包含的4种运算操作仍然是我们开头提到的实现随机性的三大变换:
-
线性变换:这里表现为行移位(ShiftRows)、列混淆(MixColumns)
-
非线性变换:S-Box字节替换(SubBytes)
-
轮密钥加(AddRoundKey)
同时,在图的右边展示的是AES解密算法的流程,可以看出解密算法的每一步分别对应加密算法的逆操作,即 加解密所有操作的顺序正好是相反的
加解密中每轮的密钥分别由种子密钥经过密钥扩展算法得到。算法中 16 字节的明文、密文和轮子密钥都以一个 4x4 的矩阵表示
下面是轮函数的详细步骤:
字节替换 SubBytes
字节替换通过S-box完成一个字节到另一个字节的映射和替换,主要用于提供密码算法的 混淆性(非线性变换)
-
S盒变换是AES的唯一的非线性变换,是AES安全的关键
-
AES使用16个相同的S盒,DES使用的是8个不同的S盒
-
AES的S盒有8位输入,8位输出,是一种非线性置换;DES的S盒有6位输入,4位输出,是一种非线性压缩
这里直接使用一个构造好的S-box,其中a为 $S$,b为 $S ^{-1}$
$S$ 和 $S ^{-1}$ 分别为 16X16
的矩阵,完成一个 8bit
输入到 8bit
输出的映射,输入的高 4bit
对应的值作为行标,低 4bit
对应的值作为列标
输入字节值为 a=a7a6a5a4a3a2a1a0
,输出值为 S[a7a6a5a4][a3a2a1a0]
,$S ^{-1}$ 的变换也同理
例如:
-
字节
00000000B
通过 $S$ 替换后的值为(S[0][0]=)63H
-
再通过 $S ^{-1}$ 即可得到替换前的值,
(S- 1 [6][3]=)00H
等价描述
-
按字节值的升序逐行初始化$S$盒子
第1行是{00},{01},…,{0F}
第2行是{10},{11},…,{1F}
以此类推,在y行 x列
的字节值是{yx}
-
$S$ 盒子中每个字节映射为有限域 $GF(2^{8})$ 中的逆,其中{00}映射为{00}
-
S 盒子中的每个字节的 8 位记为 $(b_{7},b_{6}, …, b_{0})$ ,对每个字节进行如下正变换: $ b_{i}’ = b_{i} \oplus b_{i+4mod8} \oplus b_{i+5mod8} \oplus b_{i+6mod8} \oplus b_{i+7mod8} \oplus c_{i} $
其中$c_{i}$是值{63}
字节 c 的第 i 位($c_{7}$, $c_{6}$, $c_{5}$, $c_{4}$, $c_{3}$, $c_{2}$, $c_{1}$) = (01100011) -
对应的逆变换为:
$ b_{i}’ = b_{i+2mod8} \oplus b_{i+5mod8} \oplus b_{i+7mod8} \oplus d_{i} $
其中字节 d = {05} = 00000101
行移位 ShiftRows
行移位是一个 4X4
的矩阵内部字节之间的置换,本质在于把数据打乱重排,用于提供算法的 扩散性(线性变换)
加密中的正向行移位
-
第一行保持不变
-
第二行循环左移 8 比特
-
第三行循环左移 16 比特
-
第四行循环左移 24 比特
解密中的逆向行移位
与正向行移位执行相反的操作
-
第一行保持不变
-
第二行循环右移 8 比特
-
第三行循环右移 16 比特
-
第四行循环右移 24 比特
列混淆 MixColumns
利用 $GF(2^8)$ 域上算术特性的一个代替,同样用于提供算法的 扩散性(线性变换)
加密中的正向列混淆
上述原理图中的乘法和加法都是定义在 $GF(2^8)$ 域上
可以理解为:
列混合变换把状态的列视为 $GF(2^8)$ 上的多项式 $a(x)$ 乘以一个固定的多项式 $c(x)$ ,并模一个不可约多项式 $m(x)$
不可约多项式(本原多项式),是不能写成两个次数较低的多项式之乘积的多项式,即没有因子的多项式 |
举个例子
假设:
$c(x)$ 为 $\lbrace C9 \rbrace$,即 $c(x) = x^{7} + x^{6} + x^{3} + 1$
$m(x) = x^{8} + x^{4} + x^{3} + x + 1$
则得到:
$
\lbrace 02 \rbrace· \lbrace C9 \rbrace \\
= (0000,0010)·(1100,1001) \\
= x · (x^{7} + x^{6} + x^{3} + 1) \mod (m(x)) \\
= x^{8} + x^{7} + x^{4} + x - (x^{8} + x^{4} + x^{3} + x + 1) \\
= x^{7} + x^{3} + 1 \\
= (1000,1001) \\
= \lbrace 89 \rbrace
$
解密中的逆向列混淆
逆向列混淆中则是左乘正向矩阵的逆矩阵,这样就能保证逆向列混淆后恢复明文
即:
在AES实现过程中,正向列混淆使用的矩阵要简单,所以 AES 加密计算复杂度更低,AES 解密计算复杂度更高 |
设计思想:CFB/OFB/CTR 模式仅使用 AES 加密算法,用于生成随机数来实现加密,所以需要加密矩阵的值更小,效率更高 |
轮密钥加 AddRoundKey
加密:每轮的输入与轮密钥异或一次,$c = m \oplus k$
解密:再异或上该轮的轮密钥即可恢复明文,$m = c \oplus k$
其依据的原理是“任何数和自身的异或结果为0”
这里最重要的就是轮密钥,轮密钥根据密钥扩展算法和密钥选择而产生的
密钥扩展
轮密钥在AES加解密中有着极其重要的角色
-
加密迭代中每一轮需要一个轮密钥参与加密
-
轮密钥根据密钥产生算法通过用户密钥得到
-
密钥产生分两步进行:
(1)密钥扩展
(2)轮密钥选择
-
密钥扩展将用户密钥扩展为一个扩展密钥
-
密钥选择从扩展密钥中选出轮密钥
密钥扩展算法
比如:将 16bytes(128bit) 的密钥扩展为 43bytes(344bit)
-
将种子密钥按图(a)的格式排列,
k0、k1、...、k15
依次表示种子密钥的一个字节; 排列后用 4 个 32bit 的字表示,记为w[0]、w[1]、w[2]、w[3]
4 组,每组 4 个字节 -
串行求解
w[j]
,其中 j 是整数并且属于[4,43]
-
g 函数内部也包含了线性变换、非线性变换和轮常量加
-
线性变换:将 w 循环左移 8bit
-
非线性变换:分别对每个字节做 S-box 置换
-
轮常量加:与 32bit 的常量
RC[j/4],0,0,0
进行异或, RC 是一个一维数组
-
举个例子
轮密钥选择
根据分组大小,依次从扩展密钥中取出轮密钥
前面的Nb个字作为轮密钥0,接下来的Nb个字作为轮密钥1,以此类推…
对称加密的工作模式
Q: 分组密码每次加密 128bit 的数据,如果数据为 128bit~300Gbit 数据,应该如何加密?
A: 分组密码循环调用多次,实现对任意长数据的加密
这个循环调用的方式,就成为工作模式
常见的五种工作模式
常见的五种工作模式在《图解密码技术》读书笔记(1)——对称密码与分组密码已经简单介绍过
ECB(Electronic CodeBook),电子密码本模式
- 能并行加密和解密
- 如果 P1=P2 ,则 C1=C2 密文的随机性很差
- 应用场景:仅加密 128bit 的数据
CBC(Cipher Block Chaining),密文分组链接模式
- 随机性高
- 传输错误则会影响后续解密正确性——雪崩效应
- 串行加解密
- 最后一个分组需要填充
- 需要初始化向量
- 应用场景:数据本地加密解密且数据量较小(或对速度无要求),则可用该方案;远程传输则不使用该方案
CFB(Cipher FeedBack),密文反馈模式
- 需要初始化向量
- 不能并行运算
- 不需要填充
- 传输错误则会影响后续解密正确性——雪崩效应
- 每次加密 sbit,且串行,因此效率较低
- 加密和解密过程均使用 AES 加密算法,计算效率较高
OFB(Output FeedBack),输出反馈模式
- 需要初始化向量
- 不能并行运算
- 不需要填充
- 加密和解密过程均使用 AES 加密算法,计算效率较高
- 本质上是分组密码算法构造出流密码算法,生成任意长的随机数对消息加密
CTR(CounTeR),计数器模式
- 用计数器代替OFB模式中的向量
- counter1= IV,可公开传输
- 不需要填充,独立性高, 可并行运算
- 加密和解密过程均使用 AES 加密算法,计算效率较高
- 本质上是分组密码算法构造流密码算法,生成任意长随机数对消息加密
- ECIES 加密方案中,调用 AES 对称加密时,就使用了该方案
GCM模式
GCM = MAC + CTR
目前最推荐的模式,在CTR计数器模式上添加了MAC(Message Authentication Code)消息验证码
GCM 是认证加密模式,将 MAC 和 CTR计数器模式耦合,结合二者优点
-
CTR 计数器模式: 确保数据的保密性、并行性,且具有 counter=IV 可公开等优点
-
MAC:提供附加消息的完整性校验
主要流程
发送方:
1)CTR 模式下,先对块进行顺序编号,然后将该块编号与初始向量(IV)组合,并使用密钥 k 对输入做 AES 加密,然后将加密的结果与明文进行 XOR 运算来生成密文
2)对于附加消息(共享秘钥),使用密钥 H(由密钥 K 得出),运行 GMAC,将结果与密文进行 XOR 运算,生成用于验证数据完整性的身份验证标签
接收方:
密文接收者会收到一条完整的消息,包含密文、IV(计数器 CTR 的初始值)、身份验证标签(MAC 值)
接收者先使用MAC进行数据完整性校验,再进行常规的 CTR 解密过程