常用加密算法之 SM4 简介及应用

2024-06-21 02:28

本文主要是介绍常用加密算法之 SM4 简介及应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、SM4 简介

SM4 是中国国家密码管理局提出的一种分组密码算法,也称为 SMS4。它属于对称加密算法,分组长度为 128 比特,密钥长度也为 128 比特。SM4 算法采用了与 AES 类似的轮函数结构,但具体的 S 盒和线性变换与 AES 不同,因此具有独特的加密性能。

1. 算法特点

分组长度:128 比特(16 字节)
密钥长度:128 比特(16 字节)
轮数:32 轮
安全强度:与 AES 相当,满足各种安全应用场景

2. 算法结构

SM4 算法主要由密钥扩展算法和轮函数(Round Function)组成。密钥扩展算法将 128 比特的密钥扩展成 32 个 32 比特的轮密钥。轮函数则通过非线性变换和线性变换对输入数据进行多轮迭代,最终输出加密结果。

3. 安全性

SM4 算法已经经过严格的数学分析和实际测试,证明了其具有较高的安全性。在同等密钥长度下,SM4 的安全性与 AES 相当,能够满足各种安全应用场景的需求。

二、Spring Boot集成SM4加密算法实战

1. 添加依赖

首先,需要在Spring Boot项目的 pom.xml 文件中添加Bouncy Castle库的依赖

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.68</version> <!-- 请使用最新版本 -->
</dependency>

2. 实现 SM4 帮助类

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;public class SM4Util {private static final String ALGORITHM = "SM4/CBC/PKCS5Padding";private static final String KEY = "your-128-bit-key-here"; // 密钥,长度必须是16字节private static final String IV = "your-iv-here"; // 初始化向量,长度必须是16字节/*** 生成SM4密钥** @return SecretKey 对象* @throws NoSuchAlgorithmException 如果找不到算法*/public static SecretKey generateKey() throws NoSuchAlgorithmException {KeyGenerator keyGenerator = KeyGenerator.getInstance("SM4");keyGenerator.init(128);return keyGenerator.generateKey();}/*** 加密数据** @param data 待加密的原始数据* @return 加密后的数据* @throws Exception 加密过程中可能抛出的异常*/public static String encrypt(String data) throws Exception {return encrypt(data, KEY, IV);}/*** 加密数据,允许自定义密钥和IV** @param data    待加密的原始数据* @param key     加密密钥* @param iv      初始化向量* @return 加密后的数据* @throws Exception 加密过程中可能抛出的异常*/public static String encrypt(String data, String key, String iv) throws Exception {Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");SecureRandom random = new SecureRandom(key.getBytes());IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes(), "SM4"), ivSpec);byte[] encryptedData = cipher.doFinal(data.getBytes());return Base64.getEncoder().encodeToString(encryptedData);}/*** 解密数据** @param encryptedData 已加密的数据* @return 解密后的原始数据* @throws Exception 解密过程中可能抛出的异常*/public static String decrypt(String encryptedData) throws Exception {return decrypt(encryptedData, KEY, IV);}/*** 解密数据,允许自定义密钥和IV** @param encryptedData 已加密的数据* @param key           加密密钥* @param iv            初始化向量* @return 解密后的原始数据* @throws Exception 解密过程中可能抛出的异常*/public static String decrypt(String encryptedData, String key, String iv) throws Exception {Cipher cipher = Cipher.getInstance(ALGORITHM, "BC");IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes(), "SM4"), ivSpec);byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));return new String(decryptedData);}
}
  1. 使用帮助类
    以下是如何使用SM4Util帮助类的示例:
public class SM4Demo {public static void main(String[] args) {try {// 待加密的原始数据String originalData = "Hello, World!";// 加密数据String encryptedData = SM4Util.encrypt(originalData);System.out.println("Encrypted: " + encryptedData);// 解密数据String decryptedData = SM4Util.decrypt(encryptedData);System.out.println("Decrypted: " + decryptedData);} catch (Exception e) {e.printStackTrace();}}
}

三、使用 Hutool 方式集成 SM4

  1. 引入 Hutool 工具 pom 依赖

<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.26</version>
</dependency>
  1. 使用生成的随机密钥
String content = "test中文";// 随机生成密钥
SymmetricCrypto sm4 = SmUtil.sm4();String encryptHex = sm4.encryptHex(content);
String decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);
  1. 使用自定义密钥
String content = "test中文frfewrewrwerwer---------------------------------------------------";// 生成自定义密钥
byte[] key = KeyUtil.generateKey(SM4.ALGORITHM_NAME, 128).getEncoded();SM4 sm4 = SmUtil.sm4(key);String encryptHex = sm4.encryptHex(content);
String decryptStr = sm4.decryptStr(encryptHex, CharsetUtil.CHARSET_UTF_8);

参考文献 :国密算法工具-SmUtil

这篇关于常用加密算法之 SM4 简介及应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1079948

相关文章

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

Java 字符数组转字符串的常用方法

《Java字符数组转字符串的常用方法》文章总结了在Java中将字符数组转换为字符串的几种常用方法,包括使用String构造函数、String.valueOf()方法、StringBuilder以及A... 目录1. 使用String构造函数1.1 基本转换方法1.2 注意事项2. 使用String.valu

Java中的Opencv简介与开发环境部署方法

《Java中的Opencv简介与开发环境部署方法》OpenCV是一个开源的计算机视觉和图像处理库,提供了丰富的图像处理算法和工具,它支持多种图像处理和计算机视觉算法,可以用于物体识别与跟踪、图像分割与... 目录1.Opencv简介Opencv的应用2.Java使用OpenCV进行图像操作opencv安装j

将Python应用部署到生产环境的小技巧分享

《将Python应用部署到生产环境的小技巧分享》文章主要讲述了在将Python应用程序部署到生产环境之前,需要进行的准备工作和最佳实践,包括心态调整、代码审查、测试覆盖率提升、配置文件优化、日志记录完... 目录部署前夜:从开发到生产的心理准备与检查清单环境搭建:打造稳固的应用运行平台自动化流水线:让部署像

VUE动态绑定class类的三种常用方式及适用场景详解

《VUE动态绑定class类的三种常用方式及适用场景详解》文章介绍了在实际开发中动态绑定class的三种常见情况及其解决方案,包括根据不同的返回值渲染不同的class样式、给模块添加基础样式以及根据设... 目录前言1.动态选择class样式(对象添加:情景一)2.动态添加一个class样式(字符串添加:情

Linux中Curl参数详解实践应用

《Linux中Curl参数详解实践应用》在现代网络开发和运维工作中,curl命令是一个不可或缺的工具,它是一个利用URL语法在命令行下工作的文件传输工具,支持多种协议,如HTTP、HTTPS、FTP等... 目录引言一、基础请求参数1. -X 或 --request2. -d 或 --data3. -H 或

在Ubuntu上部署SpringBoot应用的操作步骤

《在Ubuntu上部署SpringBoot应用的操作步骤》随着云计算和容器化技术的普及,Linux服务器已成为部署Web应用程序的主流平台之一,Java作为一种跨平台的编程语言,具有广泛的应用场景,本... 目录一、部署准备二、安装 Java 环境1. 安装 JDK2. 验证 Java 安装三、安装 mys

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

Node.js 中 http 模块的深度剖析与实战应用小结

《Node.js中http模块的深度剖析与实战应用小结》本文详细介绍了Node.js中的http模块,从创建HTTP服务器、处理请求与响应,到获取请求参数,每个环节都通过代码示例进行解析,旨在帮... 目录Node.js 中 http 模块的深度剖析与实战应用一、引言二、创建 HTTP 服务器:基石搭建(一

Java 枚举的常用技巧汇总

《Java枚举的常用技巧汇总》在Java中,枚举类型是一种特殊的数据类型,允许定义一组固定的常量,默认情况下,toString方法返回枚举常量的名称,本文提供了一个完整的代码示例,展示了如何在Jav... 目录一、枚举的基本概念1. 什么是枚举?2. 基本枚举示例3. 枚举的优势二、枚举的高级用法1. 枚举