Sm4【国密4加密解密】
当我们开发金融、国企、政府信息系统时,不仅要符合网络安全的等保二级、等保三级,还要求符合国密的安全要求,等保测评已经实行很久了,而国密测评近两年才刚开始。那什么是密码/国密?什么是密评?本文就关于密码/国密及应用进行基础的知识梳理、记录。
01、密码(国密)算法有哪些?
国产化替代大家应该都熟悉了,为了应对日益复杂多变的国际形势(丑国),保障我们的IT技术自助可控,从硬件到软件,都在进行着国产化替代。密码领域也不例外,国密就是用来代替国际密码的。先来了解下密码的分类,及对应的国密算法。
我国国家密码管理局在2012年公布了无线局域网产品使用的SM4密码算法——商用密码算法。
它是分组算法当中的一种,算法特点是设计简沽,结构有特点,安全高效。
数据分组长度为128比特,密钥长度为128 比特。加密算法与密钥扩展算法都采用32轮迭代结构。
SM4密码算法以字节(8位)和字(32位)作为单位进行数据处理。SM4密码算法是对合运算,因此解密算法与加密算法的结构相同,只是轮密钥的使用顺序相反,解密轮密钥是加密轮密钥的逆序。
02、SM4基本算法
SM4密码算法使用的基本运算为异或和循环移位。
异或:⊕,32位异或运算
循环移位:<<<i,把32位字循环左移i位
字:(32位)
03、依赖
<!--sm4加密算法依赖--><dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.59</version></dependency>
04、工具类
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;/*** sm4加密算法工具类* @explain sm4加密、解密与加密结果验证 可逆算法* @Autor:jingyao*/
public class Sm4Util {static {Security.addProvider(new BouncyCastleProvider());}private static final String ENCODING = "UTF-8";public static final String ALGORITHM_NAME = "SM4";// 加密算法/分组加密模式/分组填充方式// PKCS5Padding-以8个字节为一组进行分组加密// 定义分组加密模式使用:PKCS5Paddingpublic static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding";// 128-32位16进制;256-64位16进制public static final int DEFAULT_KEY_SIZE = 128;/*** 生成ECB暗号* @explain ECB模式(电子密码本模式:Electronic codebook)* @param algorithmName 算法名称* @param mode 模式* @param key* @return* @throws Exception*/private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception {Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);cipher.init(mode, sm4Key);return cipher;}/*** 自动生成密钥* @explain* @return* @throws NoSuchAlgorithmException* @throws NoSuchProviderException*/public static byte[] generateKey() throws Exception {return generateKey(DEFAULT_KEY_SIZE);}//加密******************************************/*** @explain 系统产生秘钥* @param keySize* @return* @throws Exception*/public static byte[] generateKey(int keySize) throws Exception {KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);kg.init(keySize, new SecureRandom());return kg.generateKey().getEncoded();}/*** sm4加密* @explain 加密模式:ECB 密文长度不固定,会随着被加密字符串长度的变化而变化* @param hexKey 16进制密钥(忽略大小写)* @param paramStr 待加密字符串* @return 返回16进制的加密字符串* @throws Exception*/public static String encryptEcb(String hexKey, String paramStr) throws Exception {String cipherText = "";// 16进制字符串-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// String-->byte[]byte[] srcData = paramStr.getBytes(ENCODING);// 加密后的数组byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData);// byte[]-->hexStringcipherText = ByteUtils.toHexString(cipherArray);return cipherText;}/*** 加密模式之Ecb* @param key* @param data* @return* @throws Exception*/public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception {Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);//声称Ecb暗号,通过第二个参数判断加密还是解密return cipher.doFinal(data);}//解密****************************************/*** sm4解密* @explain 解密模式:采用ECB* @param hexKey 16进制密钥* @param cipherText 16进制的加密字符串(忽略大小写)* @return 解密后的字符串* @throws Exception*/public static String decryptEcb(String hexKey, String cipherText) throws Exception {// 用于接收解密后的字符串String decryptStr = "";// hexString-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// hexString-->byte[]byte[] cipherData = ByteUtils.fromHexString(cipherText);// 解密byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData);// byte[]-->StringdecryptStr = new String(srcData, ENCODING);return decryptStr;}/*** 解密* @explain* @param key* @param cipherText* @return* @throws Exception*/public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception {Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);//生成Ecb暗号,通过第二个参数判断加密还是解密return cipher.doFinal(cipherText);}/*** 校验加密前后的字符串是否为同一数据* @explain* @param hexKey 16进制密钥(忽略大小写)* @param cipherText 16进制加密后的字符串* @param paramStr 加密前的字符串* @return 是否为同一数据* @throws Exception*/public static boolean verifyEcb(String hexKey, String cipherText, String paramStr) throws Exception {// 用于接收校验结果boolean flag = false;// hexString-->byte[]byte[] keyData = ByteUtils.fromHexString(hexKey);// 将16进制字符串转换成数组byte[] cipherData = ByteUtils.fromHexString(cipherText);// 解密byte[] decryptData = decrypt_Ecb_Padding(keyData, cipherData);// 将原字符串转换成byte[]byte[] srcData = paramStr.getBytes(ENCODING);// 判断2个数组是否一致flag = Arrays.equals(decryptData, srcData);return flag;}}
05、测试Demo
import com.example.mybatiseplusdemo.util.Sm4Util;public class Sm4Test {public static void main(String[] args) {try {System.out.println("开始测试SM4加密解密====================");String json = "{\"name\":\"大司命\",\"描述\":\"测试SM4加密解密\"}";System.out.println("加密前:"+json);//自定义的32位16进制秘钥String key = "86C63180C2806ED1F47B859DE501215B";String cipher = Sm4Util.encryptEcb(key,json);//sm4加密System.out.println("加密后:"+cipher);System.out.println("校验:"+Sm4Util.verifyEcb(key,cipher,json));//校验加密前后是否为同一数据json = Sm4Util.decryptEcb(key,cipher);//解密System.out.println("解密后:"+json);System.out.println("结束===================");} catch (Exception e) {e.printStackTrace();}}
}
相关文章:

Sm4【国密4加密解密】
当我们开发金融、国企、政府信息系统时,不仅要符合网络安全的等保二级、等保三级,还要求符合国密的安全要求,等保测评已经实行很久了,而国密测评近两年才刚开始。那什么是密码/国密?什么是密评?本文就关于密…...

git如果将多次提交压缩成一次
将N个提交压缩到单个提交中有两种方式: git reset git reset的本意是版本回退,回退时可以选择保留commit提交。我们基于git reset的作用,结合新建分支,可以实现多次commit提交的合并。这个不需要vim编辑,很少有冲突。…...
android用Retrofit进行网络请求和解析
Retrofit 的原理 Retrofit的核心原理包括动态代理与Service Method的构建、注解解析与请求配置、网络请求执行与响应处理等。它是一个类型安全的HTTP客户端,用于Android和Java平台,通过将HTTP API转化为Java接口的方式,简化了网络请求的编写…...

list容器的基本使用
目录 前言一,list的介绍二,list的基本使用2.1 list的构造2.2 list迭代器的使用2.3 list的头插,头删,尾插和尾删2.4 list的插入和删除2.5 list 的 resize/swap/clear 前言 list中的接口比较多,与string和vector类似&am…...

34万汉语词语成语反义词ACCESS\EXCEL数据库
反义词就是两个意思相反的词,包括:绝对反义词和相对反义词。分为成对的意义相反、互相对立的词。如:真——假,动——静,拥护——反对。这类反义词所表达的概念意义互相排斥。或成对的经常处于并举、对待位置的词。如&a…...
yum方式更新Jenkins
目的 使用yum方式更新Jenkins。 步骤 查看最新可用版本 $ yum list jenkins Last metadata expiration check: 0:03:44 ago on Fri Jun 14 06:10:01 2024. Installed Packages jenkins.noarch 2.452.1-1.1 jenkins Available Pa…...

欢乐钓鱼大师保姆级教程,云手机辅助攻略解析!
在这份攻略中,我们将为大家详细介绍如何在《欢乐钓鱼大师》中快速提升钓鱼技能和游戏进展,避免常见的新手误区和不必要的资源浪费。无论是钓鱼点的选择、装备的合理使用还是技能的优化,我们都会一一为您详细解析,帮助您成为一名优…...

数据结构:手撕代码——顺序表
目录 1.线性表 2.顺序表 2.1顺序表的概念 2.2动态顺序表实现 2.2-1 动态顺序表实现思路 2.2-2 动态顺序表的初始化 2.2-3动态顺序表的插入 检查空间 尾插 头插 中间插入 2.2-4 动态顺序表的删除 尾删 头删 中间删除 2.2. 5 动态顺序表查找与打印、销毁 查找 …...

jenkins使用注意问题
1.在编写流水线时并不知道当前处在哪个目录,导致名使用不当,以及文件位置不清楚 流水线任务默认路径是,test4_mvn为jenkins任务名 [Pipeline] sh (hide)pwd /var/jenkins_home/workspace/test4_mvn maven任务也是,看来是一样的…...

Kaggle -- Titanic - Machine Learning from Disaster
新手kaggle之旅:1 . 泰坦尼克号 使用一个简单的决策树进行模型构建,达到75.8%的准确率(有点低,但是刚开始) 完整代码如下: import pandas as pd import numpy as npdf pd.read_csv("train.csv&quo…...

蓝牙音频解码芯片TD5163介绍,支持红外遥控—拓达半导体
蓝牙芯片TD5163A是一颗支持红外遥控、FM功能和IIS音频输出的蓝牙音频解码芯片,此颗芯片的亮点在于同时支持真立体声&单声道、TWS功能、PWM、音乐频谱和串口AT指令控制等功能,芯片在支持蓝牙无损音乐播放的同时,还支持简单明了的串口发送A…...

windows 下 docker 入门
这里只是具体过程,有不清楚的欢迎随时讨论 1、安装docker ,除了下一步,好像也没有其他操作了 2、安装好docker后,默认是运行在linux 下的,这时我们需要切换到windows 环境下, 操作:在右下角d…...

《别让“想太多”挡了你的骑行路,对比一下更丝滑》
在探索骑行的世界时,我们往往会被一些先入为主的想法所束缚。本文将带你对比骑行与其他运动和生活方式,揭示那些阻碍你爱上骑行的认知误区。 一、年龄不是界限:骑行与跑步的比较与跑步相比,骑行同样适合所有年龄段,但它…...

hadoop和hbase对应版本关系
https://hbase.apache.org/book.html#configuration...

现代X86汇编-C和ASM混合编程举例
端午假期安装好了vs c2022,并写了个简单的汇编代码,证明MASM真的可以运行。今天需要搞一个实实在在的C和ASM混合编程的例子,因为用纯汇编的求伯君写WPS的时代一去不复返了。个别关键函数用汇编,充分发挥CPU的特色功能,偶尔还是需要…...
485. 最大连续 1 的个数
给定一个二进制数组 nums , 计算其中最大连续 1 的个数。 示例 1: 输入:nums [1,1,0,1,1,1] 输出:3 解释:开头的两位和最后的三位都是连续 1 ,所以最大连续 1 的个数是 3.示例 2: 输入:nums […...

席卷的B站《植物大战僵尸杂交版》V2.0.88整合包,PC和手机可用,含通关存档和视频教程!
今天给大家安利一款席卷B站,火爆全网的游戏——《植物大战僵尸杂交版》2.0.88整合包。 这个是网络上现存植物大战僵尸杂交版的最全整合,包含了修改工具,超强通关存档和高清工具。工具包有安装视频教程,支持手机版和pc多端使用&am…...

液晶拼接屏企业应该采取哪些措施来提升整体竞争力和市场地位呢?
步入智能科技时代以来,商显行业面对着各式各样的挑战,人工智能、AI大模型等整合中,液晶拼接屏企业应该采取哪些措施以提升整体竞争力和市场地位。下面小编个人观点简单说一下;下是一些关键的措施: 首先,加…...

PHP在线生成查询产品防伪证书系统源码
源码介绍 PHP在线生成查询产品防伪证书系统源码,源码自带90套授权证书模板,带PSD公章模板,证书PSD源文件。 环境要求:PHPMYSQL,PHP 版本请使用PHP5.1 ~5.3。 图片截图 源码安装说明 1.上传所有文件至你的空间服务器…...

遥控玩具车电机驱动应用中的双H桥驱动芯片
遥控玩具车的基本工作原理是通过无线电遥控器发送信号,这些信号被玩具车内的接收器接收并解码,从而控制玩具车的运行。根据车身外型的不同,可以分为:普通的私家房车、越野车、货柜车、翻斗车等等。遥控器的操作,如前进…...

《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...

关于nvm与node.js
1 安装nvm 安装过程中手动修改 nvm的安装路径, 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解,但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后,通常在该文件中会出现以下配置&…...
Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器
第一章 引言:语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域,文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量,支撑着搜索引擎、推荐系统、…...

ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
快刀集(1): 一刀斩断视频片头广告
一刀流:用一个简单脚本,秒杀视频片头广告,还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农,平时写代码之余看看电影、补补片,是再正常不过的事。 电影嘛,要沉浸,…...

Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...