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

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

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

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

解密轮密钥:

解密结果:

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

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

5、参考文献

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

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

[3] 国内一些技术博客

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

[5] java帮助文档

 

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

  • 12
    点赞
  • 70
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
SM4加密算法可以在FPGA上实现,具体可以采用循环架构或者流水线架构。循环架构针对资源节约进行优化,适用于资源受限的硬件设备。流水线架构则针对加密性能进行优化,适用于对吞吐量有较高要求的场景。在循环架构中,每个消息分组的加密过程需要32个时钟周期。SM4算法的硬件设计通常包括密钥扩展算法加密算法和解密算法。加密和解密算法结构相同,只是轮密钥使用的顺序相反。SM4的分组长度和密钥长度都是128位(即16字节,4字)。加密过程包括32轮迭代和一次反序变换,解密过程与加密过程完全相同,只是轮密钥的使用顺序相反 [1 [2。 需要注意的是,在FPGA上实现SM4加密算法需要相应的硬件支持和编程能力。一种实现方式是使用HDL语言如Verilog或VHDL编写SM4算法的硬件描述,并通过综合、布局布线和生成比特流等步骤将其烧录到FPGA芯片中。另一种方式是使用现有的FPGA开发板,如Xilinx或Altera的开发板,利用它们提供的开发工具和资源来实现SM4算法。具体的实现方式还需根据具体的硬件平台和需求进行调整和优化。 综上所述,SM4加密算法可以在FPGA上实现,并且可以根据具体需求选择适合的架构和实现方式 [1 [2。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [SM4分组密码算法的verilog实现(附免费可用代码)](https://blog.csdn.net/weixin_43261410/article/details/125153796)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [SM4 加密算法](https://blog.csdn.net/weixin_46455069/article/details/122991627)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [[极简教学]Java的SM3加密算法(附GitHub源码教学)](https://blog.csdn.net/qq_41579123/article/details/106571243)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FLy_鹏程万里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值