SM4算法详解(2021-12-8)
SM4算法详解
原文链接1:https://www.cnblogs.com/kentle/p/14135865.html
原文链接2:https://www.cnblogs.com/kentle/p/14135865.html
国密局官方文档:http://www.gmbz.org.cn/main/viewfile/20180108015408199368.html
使用场景
- 无需进行密钥交换的场景,如内部系统,事先就可以直接确定密钥
- 防止明文传输数据被窃取的
- 加解密速度快,适合数据内容比较大的加密场景
SM4概述
补充:密码算法中常用的一些数据单位:
**位/比特/bit*:指一个二进制位***。
***字节/byte***: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-frQl5jEG-1638947146609)(https://www.zhihu.com/equation?tex=1%5C+%E5%AD%97%E8%8A%82%3D8%5C+%E4%BD%8D)]
***字/word***: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1C5vje0e-1638947146611)(https://www.zhihu.com/equation?tex=1%5C+%E5%AD%97%3D4%5C+%E5%AD%97%E8%8A%82%3D32%5C+%E4%BD%8D)]
SM4是一种分组密码算法,其分组长度为128位(即16字节,4字),密钥长度也为128位(即16字节,4字)。其加解密过程采用了32轮迭代机制(与DES、AES类似),每一轮需要一个轮密钥(与DES、AES类似)。
加密流程
1.加密过程概述:
SM4的分组长度为4字,因此,其输入是4字的明文 ( X 0 , X 1 , X 2 , X 3 ) (X_0,X_1,X_2,X_3) (X0,X1,X2,X3)(其中 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qMVnfPla-1638947146612)(https://www.zhihu.com/equation?tex=X_i)] 表示一个32位的字),经过加密后,得到的输出是4字的密文 ( Y 0 , Y 1 , Y 2 , Y 3 ) (Y_0,Y_1,Y_2,Y_3) (Y0,Y1,Y2,Y3)(其中 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYYp2AOC-1638947146612)(https://www.zhihu.com/equation?tex=Y_i)] 表示一个32位的字)。
这个加密过程分为两步,由32次轮迭代和1次反序变换组成。
2.32次轮迭代
-
输入的明文为 128bit 的数据,将其按位拆分成 4 个 32bit 的数据 x 0 , x 1 , x 2 , x 3 x_0,x_1,x_2,x_3 x0,x1,x2,x3
当 i=0i=0 时为第一次轮变换,一直进行到 i=31i=31 结束
-
x i x_i xi 暂时不做处理,将 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 rki rki 异或得到一个 32bit 的数据,作为盒变换的输入
即 sbox-input = x i + 1 ⊕ x i + 2 ⊕ x i + 3 ⊕ r k i =x_{i+1}⊕x_{i+2}⊕x_{i+3}⊕rki =xi+1⊕xi+2⊕xi+3⊕rki,⊕符号代表异或运算
-
将 sbox_input拆分成 4 个 8bit 数据,分别进行盒变换,之后再将 4 个 8bit 输出合并成一个 32bit 的 sbox_output
-
将刚才获得的 sbox_output分别循环左移 2,10,18,24 位,得到 4 个 32bit 的结果,记移位结果为 y2,y10,y18,y24y2,y10,y18,y24
-
将移位的结果 y2,y10,y18,y24与盒变换输出 sbox_outputsbox_output 和 xixi 异或,得到 xi+4xi+4
即 xi+4=sbox_output⊕y2⊕y10⊕y18⊕y24⊕xixi+4=sbox_output⊕y2⊕y10⊕y18⊕y24⊕xi -
至此完成了一轮的加解密运算
在实际加解密过程中,上述运算要执行 32 轮,同时使用 32 个不同的 rkirki,rkirki 由密钥拓展生成 -
最后将生成的最后 4 个 32bit 数据 x35,x34,x33,x32x35,x34,x33,x32 合并成一个 128bit 的数据 outputoutput,作为最后的输出结果
解密流程
密钥扩展算法
- 密钥拓展的过程和加解密大同小异
- 输入的原始密钥 keykey 为 128bit 的数据,将其按位拆分成 4 个 3232bit 的数据 K0,K1,K2,K3K0,K1,K2,K3
- 将初始密钥 K0,K1,K2,K3K0,K1,K2,K3 分别异或固定参数 FK0,FK1,FK2,FK3FK0,FK1,FK2,FK3 得到用于循环的密钥 k0,k1,k2,k3k0,k1,k2,k3
即 k0=K0⊕FK0,k1=K1⊕FK1,k2=K2⊕FK2,k3=K3⊕FK3k0=K0⊕FK0,k1=K1⊕FK1,k2=K2⊕FK2,k3=K3⊕FK3 - 进入轮密钥 rkirki 的生成
当 i=0i=0 时为第一次轮变换,一直进行到 i=31i=31 结束 - kiki 暂时不做处理,将 ki+1,ki+2,ki+3ki+1,ki+2,ki+3 和固定参数 CKiCKi 异或得到一个 32bit 的数据,作为盒变换的输入
即 sbox_input=ki+1⊕ki+2⊕ki+3⊕ckisbox_input=ki+1⊕ki+2⊕ki+3⊕cki - 将 sbox_inputsbox_input 拆分成 4 个 8bit 数据,分别进行盒变换,之后再将 4 个 8bit 输出合并成一个 32bit 的 sbox_outputsbox_output
- 将刚才获得的 sbox_outputsbox_output 分别循环左移 13,23 位,得到 2 个 32bit 的结果,记移位结果为 y13,y23y13,y23
- 将移位的结果 y13,y23y13,y23 与盒变换输出 sbox_outputsbox_output 和 kiki 异或,得到 ki+4ki+4
即 rki=ki+4=sbox_output⊕y13⊕y23⊕kirki=ki+4=sbox_output⊕y13⊕y23⊕ki - 至此完成了一轮的加解密运算
在实际加解密过程中,上述运算要执行 32 轮,同时使用 32 个不同的 CKiCKi,CKiCKi 为固定参数 - 执行完 32 轮后,便可获得 32 个用于加解密的 rki
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)