SM4分组密码算法研究

2024-02-20 00:59
文章标签 算法 sm4 分组 密码 研究

本文主要是介绍SM4分组密码算法研究,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

SM4算法详解

  分组密码将明文数据按固定长度进行分组,并在同一密钥控制下逐组进行加密,从而将各个明文分组变换成一个个等长的密文分组。
  分组密码的设计一般基于混淆原则和扩散原则。
  混淆原则指的是将密文、明文、密钥三者之间的统计关系和代数关系变得尽可能复杂,使敌手即使获得了密文和明文,也无法求出密钥的任何信息,即使获得了密文和明文的统计规律,也无法求出明文的任何信息。
  扩散原则是将明文的统计规律和结构规律散射到相当长的一段统计中去。即,明文中的每一位会影响密文中的尽可能多的位,或者说让密文中的每一位都受到明文中的尽可能多位的影响。
分组密码主要的应用场景,包括无需进行密钥交换;防止明文传输过程被窃取;数据量大,加解密速度要求快等场景。

SM4算法流程

  SM4算法主要包括异或、移位以及盒变换操作。其中密钥拓展和加/解密为两个主要模块,其流程大同小异。
  其中,移位变换是指循环左移;盒变换将8bit输入映射到8bit输出的变换,是一个固定的变换。
  下图1给出了 SM4算法的加解密(左)和密钥拓展(右)的流程图。

图1. SM4算法实现流程
(1)加/解密模块
  加/解密算法由32次迭代运算和1次反序变换组成,具体步骤如下所述。
  设,明文输入为 ( X 0 , X 1 , X 2 , X 3 ) (X_0, X_1, X_2, X_3) X0,X1,X2,X3 X i X_i Xi为32 比特的数据,密文输出为 ( Y 0 , Y 1 , Y 2 , Y 3 ) (Y_0, Y_1, Y_2, Y_3) Y0,Y1,Y2,Y3,轮密钥为 r k i rk_i rki

  ① 当 i = 0 i=0 i=0 时为第一次轮变换,一直进行到 i = 31 i=31 i=31 结束。
  ②将 X i + 1 , X i + 2 , X i + 3 X_{i+1} , X_{i+2} , X_{i+3} Xi+1,Xi+2,Xi+3 和轮密钥 r k i rk_i rki 异或得到一个 32 32 32 比特的数据,作为盒变换的输入。即, s b o x i n p u t = X i + 1 ⊕ X i + 2 ⊕ X i + 3 ⊕ r k i sbox_{input} = X_{i+1} ⊕ X_{i+2} ⊕ X_{i+3}⊕rk_i sboxinput=Xi+1Xi+2Xi+3rki ⊕ ⊕ 符号代表异或运算。
  ③ 将 s b o x i n p u t sbox_{input} sboxinput 拆分成 4 4 4 8 8 8比特数据,分别进行盒变换,之后再将 4 4 4 8 8 8比特输出合并成一个 32 32 32 比特的 s b o x o u t p u t sbox_{output} sboxoutput
  ④ 将上一步获得的 s b o x o u t p u t sbox_{output} sboxoutput分别循环左移 2,10,18,24 位,得到 4个 32比特的结果,记移位结果为 y 2 , y 10 , y 18 , y 24 y2,y10,y18,y24 y2,y10,y18,y24。与盒变换输出 s b o x o u t p u t sbox_{output} sboxoutput X i X_i Xi 异或,得到 X i + 4 X_{i+4} Xi+4。即, X i + 4 = s b o x o u t p u t ⊕ y 2 ⊕ y 10 ⊕ y 18 ⊕ y 24 ⊕ X i X_{i+4}=sbox_{output}⊕y2⊕y10⊕y18⊕y24⊕X_i Xi+4=sboxoutputy2y10y18y24Xi
至此完成了一轮的加/解密运算。
  ⑤将最后一轮生成的 4 4 4 32 32 32比特数据 X 35 X_{35} X35 X 34 X_{34} X34 X 33 X_{33} X33 X 32 X_{32} X32 合并成一个 128 b i t 128 \ bit 128 bit 的数据输出,作为最后的密文 ( Y 0 , Y 1 , Y 2 , Y 3 ) (Y_0, Y_1, Y_2, Y_3) Y0,Y1,Y2,Y3输出。
(2) 密钥扩展模块
  密钥扩展与加/解密实现过程大同小异,具体实现过程如下所述。
  设,密钥输入为 ( M K 0 , M K 1 , M K 2 , M K 3 ) (MK_0, MK_1, MK_2, MK_3) (MK0,MK1,MK2,MK3),轮密钥输出为 K i , i ∈ { 0 , 1 , 2 , … 31 } K_i, i∈\{0,1,2,…31\} Ki,i{0,1,2,31}

   ① 将初始密钥 ( M K 0 , M K 1 , M K 2 , M K 3 ) (MK_0, MK_1, MK_2, MK_3) (MK0,MK1,MK2,MK3)分别异或固定参数 ( F K 0 , F K 1 , F K 2 , F K 3 ) (FK_0, FK_1, FK_2, FK_3) (FK0,FK1,FK2,FK3)得到用于循环的密钥 ( K 0 , K 1 , K 2 , K 3 ) (K_0, K_1, K_2, K_3) (K0,K1,K2,K3),即, K 0 = M K 0 ⨁ F K 0 K_0= MK_0⨁FK_0 K0=MK0FK0, K 1 = M K 1 ⨁ F K 1 K_1=MK_1⨁FK_1 K1=MK1FK1, K 2 = M K 2 ⨁ F K 2 K_2=MK_2⨁FK_2 K2=MK2FK2, K 3 = M K 3 ⨁ F K 3 K_3=MK_3⨁FK_3 K3=MK3FK3
   ② 进入轮密钥 K i K_i Ki 的生成, 当 i = 0 i=0 i=0 时为第一轮密钥扩展,一直进行到 i=31 结束。
   ③ 将 K i + 1 , K i + 2 , K i + 3 K_{i+1}, K_{i+2}, K_{i+3} Ki+1,Ki+2,Ki+3 和固定参数 C K i CK_i CKi异或得到一个 32 32 32 比特的数据,作为盒变换的输入。即, s b o x i n p u t = K i + 1 ⊕ K i + 2 ⊕ K i + 3 ⊕ C K i sbox_{input}=K_{i+1}⊕K_{i+2}⊕K_{i+3}⊕CK_i sboxinput=Ki+1Ki+2Ki+3CKi
   ④ 将 s b o x i n p u t sbox_{input} sboxinput 拆分成 4 4 4 8 8 8 比特数据,分别进行盒变换,之后再将 4 4 4 8 8 8比特输出合并成一个 32 32 32 比特的 s b o x o u t p u t sbox_{output} sboxoutput
   ⑤ 将上一步获得的 s b o x o u t p u t sbox_{output} sboxoutput分别循环左移 13 13 13 23 23 23 位,得到 2 2 2 32 32 32 比特的结果,记移位结果为 y 13 y13 y13, y 23 y23 y23与盒变换输出 s b o x o u t p u t sbox_{output} sboxoutput K i K_i Ki 异或,得到 K i + 4 K_{i+4} Ki+4。即, K i + 4 = s b o x o u t p u t ⊕ y 13 ⊕ y 23 ⊕ K i K_{i+4} =sbox_{output}⊕y13⊕y23⊕K_i Ki+4=sboxoutputy13y23Ki
其中每一个 K i K_i Ki即为产生的轮密钥。

具体算法实现

  SM4算法的主体代码包括加解密模块和密钥扩展模块。以下为加解密模块具体实现代码以及注释。
(1)加/解密模块

def _do(self, text: bytes, key_r: list):text_ = [0 for _ in range(4)]# 将 128bit 转化成 4x32bitfor i in range(4):text_[i] = int.from_bytes(text[4 * i:4 * i + 4], 'big')for i in range(32):box_in = text_[1] ^ text_[2] ^ text_[3] ^ key_r[i]box_out = self._s_box(box_in)temp = text_[0] ^ box_out ^ self._rot_left(box_out, 2) ^ self._rot_left(box_out,10)temp = temp ^ self._rot_left(box_out, 18) ^ self._rot_left(box_out, 24)text_ = text_[1:] + [temp]text_ = text_[::-1]  # 结果逆序# 将 4x32bit 合并成 128bitresult = bytearray()for i in range(4):result.extend(text_[i].to_bytes(4, 'big'))return bytes(result)

(2)密钥扩展模块

def _generate_key(self, key: bytes):"""密钥生成"""key_r, key_temp = [0 for _ in range(32)], [0 for _ in range(4)]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]# 将 128bit 拆分成 4x32bitfor i in range(4):temp = int.from_bytes(key[4 * i:4 * i + 4], 'big')key_temp[i] = temp ^ FK[i]# 循环生成轮密钥for i in range(32):box_in = key_temp[1] ^ key_temp[2] ^ key_temp[3] ^ CK[i]box_out = self._s_box(box_in)key_r[i] = key_temp[0] ^ box_out ^ self._rot_left(box_out, 13) ^ self._rot_left(box_out, 23)key_temp = key_temp[1:] + [key_r[i]]return key_r

SM4算法性能及可靠性分析

  分组密码算法最主要的是要保证传输信息的机密性以及完整性,才能保证信息在传输过程中不被敌手窥探到。其次,随着大数据的到来,越来越多的信息在网上传播,因此算法的性能,即,执行效率显得尤为重要。与国际主流分组密码算法进行比较,可得出表1的结果。
表1. SM4与DES和AES算法比较

项目DESAESSM4
算法结构平衡FeistelSubstitution-Permutation非平衡Feistel
计算轮数16轮10/12/14轮32轮
分组长度64128128
密钥长度64128/192/256128
加解密过程相同不同相同

算法复杂性分析

  以下可以与主流国际分组密码算法DES和算法AES在空间和时间复杂度上来进行分析,比较其三种主要分组密码算法的复杂性。
(1) 空间复杂度
   DES算法需要存储 2 2 2个IP置换矩阵, 2 × 16 × 4 2×16×4 2×16×4;扩展置换, 6 × 8 6×8 6×8;S盒代换, 16 × 4 × 8 16×4×8 16×4×8;置换选择 P C 1 PC1 PC1 7 × 8 7×8 7×8;置换选择 P C 2 PC2 PC2, 8 × 6 8×6 8×6
  SM4算法需要存储S盒,大小为 2 4 × 2 4 2^4×2^4 24×24
AES算法需要存储 2 2 2个S盒,大小为 2 × 2 4 × 2 4 2×2^4×2^4 2×24×24
  其他代码运行过程中存储的变量可忽略不计,从以上比较来看,SM4分组密码算法所需的内存空间最少,AES次之,DES则最多。
(2) 时间复杂度
  时间复杂度可以简单从计算轮数进行简单的比较,AES的计算轮数最少为 10 / 12 / 14 10/12/14 10/12/14,DES次之,为 16 16 16轮,SM4算法计算轮数最多,达 32 32 32轮。
(3) 代码运行结果比较
  采用Python语言,实现三种分组密码算法(具体代码参见 python实现)。并分别使用其进行一次加密运算,比较各自运行时所占用的内存大小以及运行时间。结果如下表2所示。
表2. 占用的内存大小以及运行时间

项目内存占用运行时间
DES24576B 365 m s 365ms 365ms
AES20480B 386 m s 386ms 386ms
SM428672B 341 m s 341ms 341ms

  从表2中的运行结果来看,SM4算法运行时需要占用更多的内存,运行时间上则更快。与理论上分析的结果不一致。

安全性分析

  首先,从密钥空间上考虑,密钥空间越大,敌手可通过穷举的方法爆破密钥的可能性就越低。DES的密钥长度为64bits,AES的密钥长度为 128 / 192 / 256 b i t s 128/192/256\ bits 128/192/256 bits,SM4的密钥长度为 128 b i t s 128\ bits 128 bits。其中密钥长度越长,则代表密钥空间越大。AES最安全,SM4次之,最后是DES。其次,从算法特性上分析,SM4和AES均包含非线性变化,得到的密文统计特性更差,则更安全。最后,从攻击的角度分析,如,差分密码分析、线性密码分析、不可能差分分析等等,公开的评估结果表明,SM4分组密码能够抵抗目前已知的所有攻击。

参考文献

[1] 吕述望等. “SM4分组密码算法综述.” 信息安全研究 2.11(2016):13.
[2] 胡景秀等. “国密算法分析与软件性能研究.” 信息网络安全 10(2021):9.

资源下载

包括完整的AES、DES以及DES分组密码算法的python代码实现。
python代码实现

这篇关于SM4分组密码算法研究的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/726552

相关文章

数据库oracle用户密码过期查询及解决方案

《数据库oracle用户密码过期查询及解决方案》:本文主要介绍如何处理ORACLE数据库用户密码过期和修改密码期限的问题,包括创建用户、赋予权限、修改密码、解锁用户和设置密码期限,文中通过代码介绍... 目录前言一、创建用户、赋予权限、修改密码、解锁用户和设置期限二、查询用户密码期限和过期后的修改1.查询用

Python中的随机森林算法与实战

《Python中的随机森林算法与实战》本文详细介绍了随机森林算法,包括其原理、实现步骤、分类和回归案例,并讨论了其优点和缺点,通过面向对象编程实现了一个简单的随机森林模型,并应用于鸢尾花分类和波士顿房... 目录1、随机森林算法概述2、随机森林的原理3、实现步骤4、分类案例:使用随机森林预测鸢尾花品种4.1

Java中的密码加密方式

《Java中的密码加密方式》文章介绍了Java中使用MD5算法对密码进行加密的方法,以及如何通过加盐和多重加密来提高密码的安全性,MD5是一种不可逆的哈希算法,适合用于存储密码,因为其输出的摘要长度固... 目录Java的密码加密方式密码加密一般的应用方式是总结Java的密码加密方式密码加密【这里采用的

关于Java内存访问重排序的研究

《关于Java内存访问重排序的研究》文章主要介绍了重排序现象及其在多线程编程中的影响,包括内存可见性问题和Java内存模型中对重排序的规则... 目录什么是重排序重排序图解重排序实验as-if-serial语义内存访问重排序与内存可见性内存访问重排序与Java内存模型重排序示意表内存屏障内存屏障示意表Int

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

mysql重置root密码的完整步骤(适用于5.7和8.0)

《mysql重置root密码的完整步骤(适用于5.7和8.0)》:本文主要介绍mysql重置root密码的完整步骤,文中描述了如何停止MySQL服务、以管理员身份打开命令行、替换配置文件路径、修改... 目录第一步:先停止mysql服务,一定要停止!方式一:通过命令行关闭mysql服务方式二:通过服务项关闭

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

康拓展开(hash算法中会用到)

康拓展开是一个全排列到一个自然数的双射(也就是某个全排列与某个自然数一一对应) 公式: X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[1]*0! 其中,a[i]为整数,并且0<=a[i]<i,1<=i<=n。(a[i]在不同应用中的含义不同); 典型应用: 计算当前排列在所有由小到大全排列中的顺序,也就是说求当前排列是第

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个