SM4加密算法(JAVA语言实现)

编程入门 行业动态 更新时间:2024-10-22 07:16:44

SM4<a href=https://www.elefans.com/category/jswz/34/1769220.html style=加密算法(JAVA语言实现)"/>

SM4加密算法(JAVA语言实现)

1、SM4算法简介

中国国家密码管理局于2006年1月6日发布第7号公告,将我国无线局域网产品的加密算法确定为SM4算法(原SMS4)。这是国内官方公布的第一个商用密码算法。

SM4分组密码算法是一个迭代分钟密码算法,由加解密算法和密钥扩展算法组成,SM4分组密码算法采用非平衡Feistel结构,明文分组长度为128bit,密钥长度为128bit。加密算法与密钥扩展算法都采用32轮非线性迭代结构。解密算法与加密算法的结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。

加密首先要生成一套加密密钥,从用户处获得一个128bit的初始密钥并将其分为4组,之后对应的与系统参数FK进行异或运算,之后将产生的结果进行32轮迭代(包含:与固定参数CKi的异或运算、S盒替换、循环移位、移位之后的异或运算)最后生成32个轮子密钥,每个轮子密钥32bit,分别供每一轮运算中使用。

SM4算法的S盒替换与AES算法中的S盒替换类似:输入的前4位为行号,后4位为列号,行列交叉点处的数值即为替换结果。

SM4算法的加密流程为首先从用户处获得128bit的明文,之后将明文分为4组,每组32bit,之后将其进过轮函数F变换,一共进行32轮次,最后再经过反序变换之后的到加密后的结果。

SM4中的合成置换T是一个可逆置换,由非线性变换 和线性变换L复合而成。其中是由4个并行的S盒代替构成。为国定的8bit输入和8bit输出的代替。并且非线性变换是线性变换L的输入。

在SM4算法中S盒是固定不变的,而且系统参数CKi的取值也是不变的,系统参数一共有32个。

SM4的解密过程与加密过程结构完全相同,不同的仅仅是轮秘钥的使用顺序。加密轮密钥的使用顺序是,

而解密时密钥的使用顺序为加密时候的反序:

 

2、密码算法程序各模块详细设计

2.1  核心模块主要实现算法的流程

 图1  SM4加密算法流程示意图

图2  SM4密钥扩展算法流程图

3、核心模块的函数说明和实现方式

3.1 轮密钥扩展算法核心代码

private void SMS4KeyExt(byte[] Key, int[] rk, int CryptFlag) {int r, mid;int[] x = new int[4];     int[] tmp = new int[4];    for (int i = 0; i < 4; i++) {
//使用下面的语句,实现对初始秘钥的分组(分为4组)tmp[0] = Key[0 + 4 * i] & 0xFF;tmp[1] = Key[1 + 4 * i] & 0xff;tmp[2] = Key[2 + 4 * i] & 0xff;tmp[3] = Key[3 + 4 * i] & 0xff;x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
x[i]=Key[0+4*i]<<24|Key[1+4*i]<<16|Key[2+4*i]<<8|Key[3+4*i];
}
/******************************** 系统参数FK的取值(取值固定)*******************************/x[0] ^= 0xa3b1bac6;	//Key (0)与FK(0)异或运算之后的结果x[1] ^= 0x56aa3350;	//Key (1)与FK(1)异或运算之后的结果x[2] ^= 0x677d9197;	//Key (2)与FK(2)异或运算之后的结果x[3] ^= 0xb27022dc;	//Key (3)与FK(3)异或运算之后的结果for (r = 0; r < 32; r += 4) {//实现K(r+1)、K(r+2)、K(r+3)与CK(i)的异或运算操作mid = x[1] ^ x[2] ^ x[3] ^ CK[r + 0];  //调用函数ByteSub实现非线性变换mid = ByteSub(mid);	// 将变换之后的结果与自身的循环左移13、23位做异或运算rk[r + 0] = x[0] ^= L2(mid); // rk0=K4  //下面的操作与以上雷同mid = x[2] ^ x[3] ^ x[0] ^ CK[r + 1];mid = ByteSub(mid);rk[r + 1] = x[1] ^= L2(mid); // rk1=K5mid = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];mid = ByteSub(mid);rk[r + 2] = x[2] ^= L2(mid); // rk2=K6mid = x[0] ^ x[1] ^ x[2] ^ CK[r + 3];mid = ByteSub(mid);rk[r + 3] = x[3] ^= L2(mid); // rk3=K7}
//CryptFlag为1时进行加密操作,CryptFlag为0时进行解密操作
// 解密时轮密钥使用顺序:rk31,rk30,...,rk0,下面主要实现对上面生成的轮子秘钥的逆序作用if (CryptFlag == DECRYPT) {for (r = 0; r < 16; r++) {mid = rk[r];rk[r] = rk[31 - r];rk[31 - r] = mid;}}}

SM4的轮密钥扩展算法严格的按照SM4轮密钥扩展算法流程图来进行操作和变换演示。

3.2 SM4加密算法核心代码

/**********************************
* 功能说明:SM4加密算法实现
* 参数说明:Input      输入的明文
* 		 Output     待输出的密文
* 		 rk         轮密钥***********************************/
void SMS4Crypt(byte[] Input, byte[] Output, int[] rk) {int r, mid;int[] x = new int[4];int[] tmp = new int[4];for (int i = 0; i < 4; i++) {tmp[0] = Input[0 + 4 * i] & 0xff;tmp[1] = Input[1 + 4 * i] & 0xff;tmp[2] = Input[2 + 4 * i] & 0xff;tmp[3] = Input[3 + 4 * i] & 0xff;x[i] = tmp[0] << 24 | tmp[1] << 16 | tmp[2] << 8 | tmp[3];
x[i]=(Input[0+4*i]<<24|Input[1+4*i]<<16|Input[2+4*i]<<8|Input[3+4*i]);}
/*************************************** 进行32轮的加密变换操作**************************************/
for (r = 0; r < 32; r += 4) {mid = x[1] ^ x[2] ^ x[3] ^ rk[r + 0];
//X(r+1)、X(r+2)、X(r+3)与轮密钥进行异或运算mid = ByteSub(mid);					//S盒置换x[0] = x[0] ^ L1(mid); // x4		//线性变换L//下面的内容操作类似mid = x[2] ^ x[3] ^ x[0] ^ rk[r + 1];mid = ByteSub(mid);x[1] = x[1] ^ L1(mid); // x5mid = x[3] ^ x[0] ^ x[1] ^ rk[r + 2];mid = ByteSub(mid);x[2] = x[2] ^ L1(mid); // x6mid = x[0] ^ x[1] ^ x[2] ^ rk[r + 3];mid = ByteSub(mid);x[3] = x[3] ^ L1(mid); // x7
}
// Reverse
/******************** 反序变换*******************/
for (int j = 0; j < 16; j += 4) {Output[j    ] = (byte) (x[3 - j / 4] >>> 24 & 0xFF);Output[j + 1] = (byte) (x[3 - j / 4] >>> 16 & 0xFF);Output[j + 2] = (byte) (x[3 - j / 4] >>> 8 & 0xFF);Output[j + 3] = (byte) (x[3 - j / 4] & 0xFF);}}

3.3 SM4解密算法核心代码

SM4的解密算法与加密算法类似,唯一不同之处就是使用的轮子密钥的顺序不同,SM4解密使用的轮子密钥与加密使用的轮子密钥正好顺序相反。在编码过程之中通过一个标志性数据——CryptFlag来确定是产生加密轮子密钥还是解密轮子密钥,当CryptFlag为1时进行加密操作,CryptFlag为0时进行解密操作。

4、程序测试

4.1 程序测试过程

在此次实验过程中为了简洁实现对编码的验证,采用直接在程序中加入代加密明文进行加密的方式,中间自动转换为16进制数据类型:

在控制台显示待加密明文与加密密钥以及加密轮密钥:

显示加密过程与加密结果:

将加密后的密文用于解密,验证程序的正确性:

解密轮密钥:

解密结果:

经过验证核实,表示正确无误,程序正确!

之后显示多分组加密结果的显示:

5、参考文献

[1] 张仕斌,万武南,张金全,孙宣东 《应用密码学》  西安电子科技大学出版社,2009.12

[2] 张健等 《密码学原理及应用技术》 清华大学出版,2011.08

[3] 国内一些技术博客

[4] 中国知网上的一些论文          

[5] java帮助文档

 

源代码下载:

更多推荐

SM4加密算法(JAVA语言实现)

本文发布于:2024-02-25 09:11:29,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1698474.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:加密算法   语言   JAVA

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!