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桥驱动芯片
遥控玩具车的基本工作原理是通过无线电遥控器发送信号,这些信号被玩具车内的接收器接收并解码,从而控制玩具车的运行。根据车身外型的不同,可以分为:普通的私家房车、越野车、货柜车、翻斗车等等。遥控器的操作,如前进…...
利用ngx_stream_return_module构建简易 TCP/UDP 响应网关
一、模块概述 ngx_stream_return_module 提供了一个极简的指令: return <value>;在收到客户端连接后,立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量(如 $time_iso8601、$remote_addr 等)&a…...
Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...
智能AI电话机器人系统的识别能力现状与发展水平
一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
JavaScript 数据类型详解
JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型(Primitive) 和 对象类型(Object) 两大类,共 8 种(ES11): 一、原始类型(7种) 1. undefined 定…...
Springboot多数据源配置实践
Springboot多数据源配置实践 基本配置文件数据库配置Mapper包Model包Service包中业务代码Mapper XML文件在某些复杂的业务场景中,我们可能需要使用多个数据库来存储和管理不同类型的数据,而不是仅仅依赖于单一数据库。本技术文档将详细介绍如何在 Spring Boot 项目中进行多数…...
【AI大模型】Transformer架构到底是什么?
引言 —— 想象一台能瞬间读懂整本《战争与和平》、精准翻译俳句中的禅意、甚至为你的设计草图生成前端代码的机器——这一切并非科幻,而是过去七年AI领域最震撼的技术革命:Transformer架构创造的奇迹。 当谷歌在2017年揭开Transformer的神秘面纱时&…...
【版本控制】Git 和 GitHub 入门教程
目录 0 引言1 Git与GitHub的诞生1.1 Git:Linus的“两周奇迹”,拯救Linux内核1.2 GitHub:为Git插上协作的翅膀1.3 协同进化:从工具到生态的质变1.4 关键历程时间轴(2005–2008) 2 Git与GitHub入门指南2.1 Gi…...
