SM4 是一种中国国家密码标准(GB/T 32907-2016)中定义的分组加密算法,又称为“中国商用密码算法SM4”。它是由中国国家密码管理局发布的,并广泛应用于金融、电子商务和其他需要数据加密的场景。
1、SM4 算法概述
SM4 是一种对称加密算法,意味着加密和解密使用相同的密钥。它是一个 128 位(16 字节)分组密码,意味着它将明文分成 128 位的块,然后对每个块进行加密。SM4 使用了 128 位的密钥进行加密和解密。
SM4 算法的主要特点是:
分组长度:128 位。
密钥长度:128 位。
加密模式:支持多种模式,如ECB(电子密码本)、CBC(加密分组链接)、CTR(计数器模式)等。
2、SM4 的工作原理
SM4 的加密和解密过程主要由以下几个部分组成:
-
密钥扩展:从 128 位的主密钥生成 32 个轮密钥,每个轮密钥长度为 32 位。
-
轮函数:加密和解密过程中,明文(或密文)经过 32 轮的迭代计算,每一轮使用一个轮密钥。
-
非线性变换函数 τ:τ 是一个基于 S 盒的非线性变换,将 32 位输入数据通过 S 盒转换为 32 位输出数据。
S 盒的每个字节输入都映射到一个输出字节。
-
线性变换函数 L:L 是一个线性变换函数,它对输入数据进行移位和异或操作来实现扩散效果。
C=L(B)=B⨁(B<<<2)⨁(B<<<10)⨁(B<<<18)⨁(B<<<24)
3、SM4 的实现步骤
3.1 参数设置
- 输入数据:128 位的明文或密文数据。
- 密钥:128 位的加密密钥。
- 轮数:32 轮加密或解密操作。
3.2 密钥扩展 (Key Expansion)
SM4 使用一个 128 位的主密钥 MK 生成 32 个轮密钥 RK。
通过以下步骤生成轮密钥:
- 密钥初始化:将 MK 分为四个 32 位的部分 MK[0], MK[1], MK[2], MK[3],然后通过线性变换得到 K[0], K[1], K[2], K[3]。
- 轮密钥生成:从 K[0] 到 K[3] 开始,通过每轮的线性变换和非线性变换生成新的密钥 K[i],最终得到 32 个轮密钥 RK[0] 到 RK[31]。
3.3 加密过程 (Encryption Process)
加密过程包括 32 轮迭代,每轮都使用一个不同的轮密钥 RK。
具体步骤如下:
- 数据初始化:将 128 位明文 P 分为四个 32 位的部分 X[0], X[1], X[2], X[3]。
- 32 轮迭代:对于每一轮 i,执行以下操作:
- 使用非线性变换函数 τ 和线性变换函数 L,结合当前状态 X[i-3], X[i-2], X[i-1], X[i] 和轮密钥 RK[i] 计算新状态 X[i+1]。
- 新状态的计算公式为:
X[i+1]=X[i−3]⊕L(τ(X[i]⊕X[i−1]⊕X[i−2]⊕RK[i]))
- 最终状态:在第 32 轮结束后,四个 32 位的状态 X[35], X[34], X[33], X[32] 将作为加密后的密文输出。
3.4 解密过程 (Decryption Process)
- 解密过程与加密过程类似,但轮密钥的使用顺序相反。
- 使用与加密相同的函数和操作步骤,只是在每轮中使用的轮密钥顺序相反,即从 RK[31] 到 RK[0]。
4、数据举例
- 明文(128 位):0x0123456789ABCDEFFEDCBA9876543210
- 密钥(128 位):0x0123456789ABCDEFFEDCBA9876543210
4.1 密钥扩展 (Key Expansion)
首先,将 128 位的密钥 MK 分为四个 32 位的部分:
MK[0] = 0x01234567
MK[1] = 0x89ABCDEF
MK[2] = 0xFEDCBA98
MK[3] = 0x76543210
接下来,定义系统参数 FK 和 CK,然后通过公式生成初始密钥 K[0], K[1], K[2], K[3]。计算过程如下:
K[0] = MK[0] ⊕ FK[0]
K[1] = MK[1] ⊕ FK[1]
K[2] = MK[2] ⊕ FK[2]
K[3] = MK[3] ⊕ FK[3]
假设 FK 的值为:
FK[0] = 0xA3B1BAC6
FK[1] = 0x56AA3350
FK[2] = 0x677D9197
FK[3] = 0xB27022DC
计算得到:
K[0] = 0xA3B1BAC6 ⊕ 0x01234567 = 0xA3928FE1
K[1] = 0x56AA3350 ⊕ 0x89ABCDEF = 0xDF01FE9F
K[2] = 0x677D9197 ⊕ 0xFEDCBA98 = 0x9971AB0F
K[3] = 0xB27022DC ⊕ 0x76543210 = 0xC42410CC
通过 32 轮迭代生成每一轮的轮密钥 RK。在此只演示前几轮的轮密钥生成:
RK[0] = K[0] ⊕ L(τ(K[1] ⊕ K[2] ⊕ K[3] ⊕ CK[0]))
RK[1] = K[1] ⊕ L(τ(K[2] ⊕ K[3] ⊕ RK[0] ⊕ CK[1]))
4.2 加密过程 (Encryption Process)
将 128 位的明文 P 分为四个 32 位的部分:
X[0] = 0x01234567
X[1] = 0x89ABCDEF
X[2] = 0xFEDCBA98
X[3] = 0x76543210
通过 32 轮迭代计算每一轮的新状态 X[i+1]。同样,我们只演示前几轮的计算:
X[4] = X[0] ⊕ L(τ(X[1] ⊕ X[2] ⊕ X[3] ⊕ RK[0]))
X[5] = X[1] ⊕ L(τ(X[2] ⊕ X[3] ⊕ X[4] ⊕ RK[1]))
以此类推,直至第 32 轮计算完成。
4.3 最终密文生成
在第 32 轮结束后,四个 32 位的状态 X[35], X[34], X[33], X[32] 将作为加密后的密文输出。最终密文将是这四个 32 位状态的组合。
例如,假设最终结果为:
X[32] = 0xF58A8A5C
X[33] = 0x70F7C3A7
X[34] = 0xA8E62D79
X[35] = 0xD2F0C1BC
则输出密文为:0xF58A8A5C70F7C3A7A8E62D79D2F0C1BC
4.4 解密过程
解密过程与加密过程类似,只需将轮密钥 RK 的顺序逆转,从 RK[31] 到 RK[0] 使用同样的操作。
5、应用模式
SM4 可以结合多种模式使用,例如 ECB(电子密码本模式)、CBC(密码分组链接模式)、CFB(密码反馈模式)、OFB(输出反馈模式)等,以适应不同的应用场景。
6、python实现(ECB模式)
# SM4 Implementation in Python
# Constants used in SM4
FK = [0xA3B1BAC6, 0x56AA3350, 0x677D9197, 0xB27022DC]
CK = [
0x00070E15, 0x1C232A31, 0x383F464D, 0x545B6269, 0x70777E85, 0x8C939AA1, 0xA8AFB6BD, 0xC4CBD2D9,
0xE0E7EEF5, 0xFC030A11, 0x181F262D, 0x343B4249, 0x50575E65, 0x6C737A81, 0x888F969D, 0xA4ABB2B9,
0xC0C7CED5, 0xDCE3EAF1, 0xF8FF060D, 0x141B2229, 0x30373E45, 0x4C535A61, 0x686F767D, 0x848B9299,
0xA0A7AEB5, 0xBCC3CAD1, 0xD8DFE6ED, 0xF4FB0209, 0x10171E25, 0x2C333A41, 0x484F565D, 0x646B7279
]
# S-box
SBOX = [
# 16x16 S-Box Table
0xd6, 0x90, 0xe9, 0xfe, 0xcc, 0xe1, 0x3d, 0xb7, 0x16,