原文链接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次轮迭代

img

  • 输入的明文为 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+1xi+2xi+3rki,⊕符号代表异或运算

  • 将 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,作为最后的输出结果


image-20211201142401158


image-20211201144535036

image-20211201144624585


解密流程

image-20211201142417177

密钥扩展算法

  • 密钥拓展的过程和加解密大同小异
  • 输入的原始密钥 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

image-20211201142439883


Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐