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

SM4加密算法(JAVA语言实现)1、SM4算法简介中国国家密码管理局于2006年1月6日发布第7号公告,将我国无线局域网产品的加密算法确定为SM4算法(原SMS4)。这是国内官方公布的第一个商用密码算法。SM4分组密码算法是一个迭代分钟密码算法,由加解密算法和密钥扩展算法组成,SM4分组密码算法采用非平衡Feistel结构,明文分组长度为128bit,密钥长度为128bit。加密算法与密钥扩展算法都采用32轮非线性迭代结…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

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是一个可逆置换,由非线性变换SM4加密算法(JAVA语言实现) 和线性变换L复合而成。其中SM4加密算法(JAVA语言实现)是由4个并行的S盒代替构成。为国定的8bit输入和8bit输出的代替。并且非线性变换是线性变换L的输入。

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

SM4的解密过程与加密过程结构完全相同,不同的仅仅是轮秘钥的使用顺序。加密轮密钥的使用顺序是SM4加密算法(JAVA语言实现),

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

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

 

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

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

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

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

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

图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=K5
			
			mid = x[3] ^ x[0] ^ x[1] ^ CK[r + 2];
			mid = ByteSub(mid);
			rk[r + 2] = x[2] ^= L2(mid); // rk2=K6
			
			
			mid = 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); // x5

	mid = x[3] ^ x[0] ^ x[1] ^ rk[r + 2];
	mid = ByteSub(mid);
	x[2] = x[2] ^ L1(mid); // x6

	mid = 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进制数据类型:

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

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

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

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

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

解密轮密钥:

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

解密结果:

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

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

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

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

5、参考文献

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

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

[3] 国内一些技术博客

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

[5] java帮助文档

 

源代码下载:https://download.csdn.net/download/fly_hps/10724893

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/185639.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 打印机服务器显示未连接,解决win10打印机提示“无法连接打印机 后台处理程序未运行”的方法…

    打印机服务器显示未连接,解决win10打印机提示“无法连接打印机 后台处理程序未运行”的方法…如今大家在办公室中最常见的两样设备就数电脑和打印机了吧?办公人员对于打印机的使用是非常频繁的,每天都要使用。因此一旦打印机出现故障就会对我们的工作效率产生影响。近日有用户将电脑升级为win10之后发现自己的打印机不能正常的运行,每次点击打印之后就会出现:“无法连接到打印机,后台处理程序未运行”的提示。不知道你遇到这个故障的时候是如何解决的,若是还没有找到解决的方法可以使用下面的教程进行处理哦!方法…

    2022年5月1日
    156
  • postMessage详解

    postMessage详解目录一、概述二、详解一、概述作用该方法是HTML5引入的API,可以通过异步方式实现跨源通信,多用于窗口间数据通信。它提供了一种受控机制来规避不同源脚本无法通信的限制,只要正确使用,这种方法很安全。什么是跨源同源即指相同的协议、域名或IP、端口号。浏览器具有同源限制,同源脚本可以相互通信,一般非同源(跨源)的脚本文件禁止相互通信。二、详解语法示例-发送程序&…

    2022年7月15日
    16
  • DLL注入之使用SetWindowsHookEx注入「建议收藏」

    DLL注入之使用SetWindowsHookEx注入「建议收藏」原理分析:本次介绍的是使用全局钩子的方式进行注入。在Windows中可以使用SetWindowsHookEx来设置消息钩子,这个函数除了可以设置当前进程的钩子之外,它还可以设置全局钩子。全局钩子,顾名思义,即当前正在运行的进程都会被设置相应的钩子。//dwThreadId设置为0,则是全局钩子。HHOOKSetWindowsHookExA(intidHook,…

    2022年5月13日
    43
  • 与运算或运算非运算异或运算是什么_俄称击退乌军进攻

    与运算或运算非运算异或运算是什么_俄称击退乌军进攻按位与运算符(&)参加运算的两个数据,按二进制位进行“与”运算。运算规则:0&0=0;  0&1=0;   1&0=0;    1&1=1;      即:两位同时为“1”,结果才为“1”,否则为0例如:3&5 即00000011&00000101=00000001  因此,3&5的值得1。 另,负数按补码形式参加按位与运算。“与运算”的特殊用途:(1

    2025年6月8日
    4
  • WinSCP连接VMware虚拟机被拒绝「建议收藏」

    WinSCP连接VMware虚拟机被拒绝「建议收藏」最近在做一个电商项目练手,使用了dubbo,并安装了虚拟机准备模拟熟悉一下,但是使用WinSCP一直提示拒绝连接,下面分享下我的解决办法期望对你们有帮助1.提示信息2.一开始的分析,以为是IP地址错误导致,所有ping了IP显示如下:3.分析IP地址,eth0上面显示的并不是我们常看到的4位的IP127.0.0.1这一类,继续分析可能是没有连网络,意思是:虚拟机也需要单独连接网

    2025年12月14日
    2
  • let’s encrypt免费证书 制作 HTTPS证书[通俗易懂]

    let’s encrypt免费证书 制作 HTTPS证书

    2022年3月5日
    160

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号