【密码学】(三)国密SM4算法

  • ~2.92K 字
  1. 1. 一、SM4概述
  2. 2. 二、SM4的加密过程
  3. 3. 三、SM4的解密过程
  4. 4. 四、SM4轮函数 的构造
  5. 5. 五、SM4的密钥扩展算法

本文转载自:《现代密码学》课程笔记知乎专栏
仅作个人学习记录。

SM4是一种分组密码算法,由我国国家密码管理局在2012年发布,常用于无线互联网加密等领域。

一、SM4概述

补充:密码算法中常用的一些数据单位:
位/比特/bit:指一个二进制位
字节/byte
字/word

SM4是一种分组密码算法,其分组长度为128位(即16字节4字),密钥长度也为128位(即16字节4字)。其加解密过程采用了32轮迭代机制(与DES、AES类似),每一轮需要一个轮密钥(与DES、AES类似)。

二、SM4的加密过程

1、加密过程概述:

SM4的分组长度为4字,因此,其输入是4字的明文 (其中 表示一个32位的字),经过加密后,得到的输出是4字的密文 (其中 表示一个32位的字)。

这个加密过程分为两步,由32次轮迭代1次反序变换组成。

2、32次轮迭代:

首先,我们需要对这个4字明文进行32次轮迭代。每一轮轮迭代都需要一个1字的轮密钥,总共需要32个轮密钥,记为 $rk0,rk_1,\ldots,rk{31}rk_ii$ 轮(这里从0开始算)迭代使用,长为1字)。之后会讲如何由原密钥得到32个轮密钥。

迭代的过程就是不断地使用轮函数 ,往后计算下一个字。

这里插一句:轮函数 $F(Xi,X{i+1},X{i+2},X{i+3},rki)$ ,它可以接收4个1字的明文和1个1字的轮密钥作为参数,最终**产生一个1字的结果**。之后会详细讲轮函数的构造。_

例如:我们现在给了4字明文 $X0,X_1,X_2,X_3使X_4=F(X_0,X_1,X_2,X_3,rk_0)X_5=F(X_1,X_2,X_3,X_4,rk_1)X{i+4}=F(Xi,X{i+1},X{i+2},X{i+3},rki)i=0,1,\ldots,31$,从0开始计数),执行32轮最终,我们一共可以得到36个字 $X_0,X_1,\ldots,X{35}$。到这里,我们就完成了加密过程的第一步。

3、一次反序变换:

加密过程的第二步是一次简单的反序变换。将迭代最后得到的四个字 $(X{32},X{33},X{34},X{35})C=(X{35},X{34},X{33},X{32})$。

这就是整个加密变换的过程。

三、SM4的解密过程

SM4的解密过程与加密过程完全相同,也包括32轮迭代和一次反序变换。只是在轮迭代的时候,需要将轮密钥逆序使用。比如对 $rk0,rk_1,\ldots,rk{31}使rk{31}使rk{30}$,以此类推。

四、SM4轮函数 的构造

1、轮函数概述:

前文提到,轮函数 接收5个1字的参数,前4个字 $Xi,X{i+1},X{i+2},X{i+3}rk_i$。轮函数的输出结果为1字。

轮函数内部需要执行的运算为 $F(Xi,X{i+1},X{i+2},X{i+3},rki)=X_i\oplus T(X{i+1}\oplus X{i+2}\oplus X{i+3}\oplus rk_i)$。

公式后边的 合成置换

2、合成置换

合成置换 接收1字的输入 ,得出1字的输出 。它包含非线性变换 线性变换 两个过程,即

(1)非线性变换

非线性变换接收1字(即4个字节)的输入,记为 (其中 为一个字节),输出1字的结果,记为

非线性变换就是对输入参数的每个字节进行S盒(Sbox)变换,得到输出结果,即

S盒如下图所示:

图6-1 SM4的S盒(第一部分)

图6-2 SM4的S盒(第二部分)

具体代换方法与AES中的字节代替相同。首先把一个字节的8位二进制写成2位十六进制,然后以十六进制的第一个数字为行,第二个数字为列,在S盒表中查找对应的数字。这样就可以把一个字节代替成另一个字节。例如

(2)线性变换

补充:
循环左移的概念:在密码学中,常对一个数据进行循环左移。具体做法就是,把数据向左移动若干位,左边溢出的数字补到右边。例如:对1234567左移三位,得到4567123。
我们使用 Undefined control sequence \lll 符号来表示对一个循环左移,例如 Undefined control sequence \lll 表示对 循环左移3位。

线性变换接收1字的 作为输入,经过运算,得出1字的输出

运算公式如下:

Undefined control sequence \lll

经过非线性变换和线性变换,就完成了一次轮迭代,计算出了下一个字的内容。

五、SM4的密钥扩展算法

前文提到,SM4的密钥为128位(4字)。然而,在32轮迭代中,每一轮都需要一个1字的轮密钥。如何由4字的原始密钥获得32个1字的轮密钥?这个问题就要靠密钥扩展算法来解决。

原始4字加密密钥为 (其中 为1字)。

1、与系统参数异或——初始化密钥:

首先需要让原始密钥的每个字 与系统参数 异或,得到4个新的字 ,即

这里系统参数的取值为

图6-3 四个系统参数的取值

2、轮迭代生成轮密钥:

(1)迭代方法:

在对密钥进行初始化后,我们得到了4个新的字

之后,与加密过程类似,需要对这四个字进行32轮迭代,生成32个轮密钥。

第一轮迭代为:

根据前面的4个字 ,计算出第5个字 的值,并且将 作为第一轮的轮密钥 ,计算方法如下:

。(这里的 类似于合成置换 为固定参数,后边会讲

第二轮迭代为:

根据 ,计算出第6个字 的值,并且将 作为第二轮的轮密钥 ,计算方法如下:

以此类推,一直进行32轮,直到得到32个轮密钥。这32个轮密钥就是密钥扩展算法的结果。

其通式为:

图6-4 密钥扩展迭代通式

(2)置换

密钥扩展算法中的 与加密过程中的合成置换 完全类似,也包括非线性变换和线性变换两部分。其中 的非线性变换部分与 完全相同。 的线性变换与 稍有区别,其线性变换 如下:

图6-5 密钥扩展算法中T的线性变换

(3)固定参数 的取值:

一共有32个 ,即计算每一轮的轮密钥时,均需要使用不同的

$CKi(ck{i,0},ck{i,1},ck{i,2},ck_{i,3})$。

假设 $ck{i,j}iCK_ijck{i,j}=(4i+j)\times7\bmod 256$。

通过这样的计算方法,就可以得到32个 ,从而运用到每一轮轮密钥的生成上去。

附:

32个 的具体值为:

图6-6 32个CKi的具体值

解密时,轮密钥的生成方法与加密一致。

附:

SM4算法总结图示:

图6-7 SM4算法总结图示