SM4密码
SM4
SM4是一个对称加密算法
- 明文分组长度:128位 16字节 4字
- 密钥长度:128位 16字节 4字
- 迭代次数:32次
字:SM4 内部把 128 位分成 4 个 32 位字,记作:
$$
X_{0},X_{1},X_{2},X_{3}
$$
轮:SM4 要迭代 32 轮。每一轮用一个 32 位“轮密钥”
S 盒:一个固定的 8 位进、8 位出的替换表,用来制造非线性。SM4 的 S 盒有 256 项,教学时先理解“查表替换”即可。
循环左移:把 32 位二进制整体左移,移出去的高位补到低位。记作 B<<<n,用于在比特层面进一步扩散复杂度
概览
正如所有的对称加密一样,加密和解密用的是同一个密钥和密文。
可以记住以下流程:
128 位主密钥 → 密钥扩展 → 32 个轮密钥
128 位明文 → 32 轮加密 → 128 位密文
解密 = 同样的 32 轮,但轮密钥倒着用
全流程大概是:
1 | |
密码学中的零件
异或⊕
异或凭借自逆的特点,被广泛运用在加解密中。
$$
a \oplus b \oplus b = a
$$
那么A就是明文,经过密钥处理两次后就能够还原回明文。
S盒
凯撒密码是一种单表替换密码,通过将明文中的每个字母沿字母表固定位移若干位来加密消息。 位移量为 3 时,A 变为 D,B 变为 E,Z 循环回绕变为 C。
实际上线性是非常危险的,因为一旦攻击者摸清了位移量,加密就不再有意义,所以采取一次非线性措施是非常重要的。
把 32 位字拆成 4 个字节,每个字节查一张固定的 8 进 8 出表,输入一个字节,输出一个字,而这张表就是S盒
循环左移异或
32 位循环左移记作 B⋘n:左移 n 位,移出去的位补到低位。
相当于将密文放到一个环中,朝着某个方向转动几位,随后敲定。
这能够将之前某一段的变化扩大到整个密文中,这种操作叫做扩散
轮函数
一轮的变换函数为:
$$
T \left( x \right)=L \left( S \left( x \right) \right)
$$
其中S(x)对32位字的4个字节做S盒替换
L为之前提到的循环左移异或
所以 T 的流程是:
32 位输入 → 4 字节 S 盒替换 → 五个循环移位版本异或 → 32 位输出
轮加密
$$
\text{设轮密钥为} rk_{0},rk_{1},\ldots,rk_{31}, \text{明文四字为} X_{0},X_{1},X_{2},X_{3}, \text{对} i=0 \text{到} 31\colon
$$
$$
X_{i+4}=X_{i}\oplus T\big(X_{i+1}\oplus X_{i+2}\oplus X_{i+3}\oplus rk_{i} \big)
$$
每一轮都做四件事
取出后三个字
将后三个字和轮密钥异或
经过轮函数T
与最旧的字异或得到新字X(i+4)
经过32轮后再加上倒反序,就形成了
$$
( Y_{0},Y_{1},Y_{2},Y_{3} ) = ( X_{35},X_{34},X_{33},X_{32} )
$$
密钥扩展
上一个条目提到,需要32次加密,那就需要32个密钥,但是主密钥只有一个128位的,这就需要密钥扩展
主密钥 128 位也拆成四个 32 位字:
$$
MK_{0},MK_{1},MK_{2},MK_{3}
$$
与固定向量FK异或
$$
K_{0}=MK_{0}\oplus FK_{0},\quad\ldots,\quad K_{3}=MK_{3}\oplus FK_{3}
$$
然后将K值用和轮加密相近的方式拿到密钥
$$
rk_{i}=K_{i+4}=K_{i}\oplus T^{\prime}(K_{i+1}\oplus K_{i+2}\oplus K_{i+3} \oplus CK_{i})
$$
CK是一个32轮常向量,用公式生成
$$
ck_{i,j}=(4i+j)\times7\ \mathrm{mod}\ 256
$$
解密
注,解密结构和加密完全一样。
$$
Y_{i+4}=Y_i\oplus T(Y_{i+1}\oplus Y_{i+2}\oplus Y_{i+3}\oplus rk_{31-i})
$$
最后输出
$$
(Y_{35},Y_{34},Y_{33},Y_{32})
$$
唯一区别是轮密钥逆序使用。原因很直观:加密每轮用异或把新字“叠”进去,异或可逆;把轮密钥倒过来,就能一层层还原。