Java聚合对外网关,使用国密SM4采用CBC分组填充模式实现数据加密工具类,Jmeter压测

添加依赖配置

		<!-- 仓库地址: https://mvnrepository.com/artifact/commons-codec/commons-codec -->
		<!--	org.apache.commons.codec.binary.Base64	-->
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.15</version>
		</dependency>

		<!-- 国密 sm4 依赖jar包 -->
		<dependency>
			<groupId>org.bouncycastle</groupId>
			<artifactId>bcprov-jdk15on</artifactId>
			<version>1.68</version>
		</dependency>

国密SM4并采用CBC分组填充模式,密钥长度为16字节。nonce为16字节,加密使用的nonce和加签一致。
1、密钥为提供提供,nonce为请求中随机生成的字符串
2、使用nonce作为iv
3、使用key、iv,对敏感数据进行加密,得到JSON形式的资源对象
4、对JSON形式的资源对象进行 Base64 编码

工具类实现,如下代码对iv赋值做了简写,可结合自身需要修改:

import com.alibaba.fastjson2.JSON;
import com.risk.decision.params.ConfirmParams;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.*;

/**
 * @Author 国密4工具类
 * @Date 2023/10/19 14:21
 * @Description 数据加密解密
 **/
public class Sm4CBCUtils {

    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    public static final String SM4 = "SM4";
    public static final String SM4_CBC_PADDING = "SM4/CBC/PKCS5Padding";

    /**
     * 参数加密
     * @param secretKey 秘钥值
     * @param decryptContext 加密的信息
     * @return String 加密后的值
     * @throws Exception 异常信息
     */
    public static String encryptCBCPadding(String secretKey, String decryptContext) throws Exception {
        Cipher cipher = encryptGenerateCbcCipher(Cipher.ENCRYPT_MODE, secretKey.getBytes());
        byte[] bytes = cipher.doFinal(decryptContext.getBytes());
        byte[] ciphertext = Base64.encodeBase64(bytes);
        return new String(ciphertext, StandardCharsets.UTF_8);
    }

    public static Cipher encryptGenerateCbcCipher(int mode, byte[] key) throws Exception {
        Key sm4Key = new SecretKeySpec(key,SM4);
        Cipher cipher = Cipher.getInstance(SM4_CBC_PADDING, BouncyCastleProvider.PROVIDER_NAME);
        byte[] iv = new byte[16];
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(mode, sm4Key, ivParameterSpec);
        return cipher;
    }


    /**
     * 接口解密
     * @param secretKey 秘钥值
     * @param decryptContext 加密的参数
     * @return String 解密的信息
     * @throws Exception 异常信息
     */
    public static String decryptCBCPadding(String secretKey, String decryptContext) throws Exception {
        byte[] decodedBytes = Base64.decodeBase64(decryptContext.getBytes(StandardCharsets.UTF_8));
        Cipher cipher = decryptGenerateCbcCipher(Cipher.DECRYPT_MODE, secretKey.getBytes());
        byte[] bytes = cipher.doFinal(decodedBytes);
        return new String(bytes, StandardCharsets.UTF_8);
    }

    public static Cipher decryptGenerateCbcCipher(int mode, byte[] key) throws Exception {
        Key sm4Key = new SecretKeySpec(key,SM4);
        Cipher cipher = Cipher.getInstance(SM4_CBC_PADDING, BouncyCastleProvider.PROVIDER_NAME);
        // 16字节的偏移向量
        byte[] iv = new byte[16];
        IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
        cipher.init(mode, sm4Key, ivParameterSpec);
        return cipher;
    }


}

注: 关于iv值的说明:

在SM4算法中,CBC模式是一种常用的分组密码模式。vi(Initialization Vector)是CBC模式中的初始向量,它的作用是为了增加密码的安全性和随机性

vi是一个固定长度的随机数,它与明文进行异或运算后再进行加密。vi的作用在于使得相同的明文在不同的加密过程中产生不同的密文,增加了密码的随机性。这样做的好处是即使明文相同,密文也会有所不同,从而增加了密码的安全性。

vi是一个必须满足一定要求的随机数,不能随意写死。如果vi被写死为固定的值,那么相同的明文每次加密后都会生成相同的密文,这样就破坏了CBC模式的安全性,攻击者可以通过观察密文的重复模式来推断出明文的信息。

因此,vi需要在每次加密过程中都是随机且不可预测的。一种常见的做法是每次加密时生成一个随机的vi,并将其与密文一起存储或传输,在解密时使用相同的vi进行解密操作。这样可以确保每次加密的结果都是不同的,从而提高密码的安全性。

测试方法:

    public static void main(String[] args) throws Exception {
        ConfirmParams confirmParams = new ConfirmParams();
        confirmParams.setPhoneCode("12388889999");
        confirmParams.setIdCode("999888202309096666");
        String strParams = JSON.toJSONString(confirmParams);
        String secretKey = "qwertyuiop123456";

        // 数据加密
        String encodedText = encryptCBCPadding(secretKey, strParams);
        System.out.println(String.format("加密后的值: %s",encodedText));

        // 数据解密
        String decryptContext = decryptCBCPadding(secretKey, encodedText);
        System.out.println(String.format("解密后的值: %s",decryptContext));

    }

结果打印:

加密后的值: B7Ug2lFn95m8J2JwNdNPt4VKqWV5NF8HCy5Fx0WfEchBGn3uhcDU1Ko6NBwinCieujp5ko2dCkzzIoYcEkm65g==
解密后的值: {"idCode":"999888202309096666","phoneCode":"12388889999"}

接口压测:

服务信息:2台Linux服务器(HA),负载均衡

Jmeter压测: Jmeter安装在Windows环境,受可使用端口的影响,设置50线程,压测40秒

添加断言,方法中处理解密异常,响应码为501,如果断言响应码包含501,则代表响应成功。不包含则表示响应失败。

压测结果,异常率100%,表示接口中并没有返回501的响应码,即解密方法是稳定的,如图:

国密4加密工具ECB模式查看上一篇文章:

SM4国密4在jdk1.7版本和jdk1.8版本中的工具类使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/154288.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

操作系统 day10(调度的概念、层次、七状态模型)

调度的概念 调度的层次 作业调度&#xff08;高级调度&#xff09; 进程调度&#xff08;低级调度&#xff09; 内存调度&#xff08;中级调度&#xff09; 挂起态与七状态模型 三层调度的联系和对比

windows虚拟内存自定义分配以及mysql错误:Row size too large (> 8126)

文章目录 虚拟内存概要windows-server配置虚拟内存技术名词解释关于mysql错误Row size too large (> 8126)问题分析解决办法 虚拟内存概要 虚拟内存别称虚拟存储器&#xff08;Virtual Memory&#xff09;。电脑中所运行的程序均需经由内存执行&#xff0c;若执行的程序占用…

软件测试需求分析

1.1 需求的重要性 1.1.1 软件缺陷的8020原则 1) 在软件测试过程中&#xff0c;从需求分析开始到集成测试阶段引入测试手段&#xff0c;能发现所有缺陷的80%&#xff1b;系统测试阶段引入测试手段&#xff0c;能发现剩余缺陷中80%的缺陷&#xff1b;在运行维护阶段经过长…

Android BitmapFactory.decodeResource读取原始图片装载成原始宽高Bitmap,Kotlin

Android BitmapFactory.decodeResource读取原始图片装载成原始宽高Bitmap&#xff0c;Kotlin fun getOriginalBitmap(resId: Int): Bitmap {val options BitmapFactory.Options()options.inJustDecodeBounds true //只解析原始图片的宽高&#xff0c;不decode原始文件装载到内…

三江城115m²3室2厅2卫,现代简约不单是居所更是对生活的向往。福州中宅装饰,福州装修

【前言】 简洁有力&#xff0c;静默无声。 以简约精致的方式&#xff0c;展现现代都市生活&#xff1b; 经典不因潮流褪色&#xff0c;不为悦人只为悦己。 项目信息 项目名称 | 三江城 设计地址 | 福建福州 项目面积 | 115㎡ 项目户型 | 3室2厅 设计风格 | 现代简约 全…

代码随想录算法训练营Day 53 || 1143.最长公共子序列、1035.不相交的线、53. 最大子序和

1143.最长公共子序列 力扣题目链接 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长公共子序列的长度。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff08;也可以不删除任何…

对象存储OSS服务器邀请试用

文章目录 试用产品领取产品试用权限上传文件开启加速传输提交作品小程序提交任务获取奖励 试用产品 先下载要上传的资源 电脑浏览器打开此页面开始试用&#xff0c;页面如下图 未登录的先登录 领取产品试用权限 在该页面中点击立即试用&#xff0c;弹框勾选服务协议并领取试…

第一百七十五回 如何创建放射形状渐变背景

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在 上一章回中介绍了"如何创建扇形渐变背景"相关的内容&#xff0c;本章回中将介绍" 如何创建放射形状渐变背景"。闲话休提&#xff0c;让我们一起Talk Flutter吧…

在test用户下创建test1表并插入数据,然后将tes1t表的查询权限授予test2用户

文章目录 1、以 test 用户登录2、创建 test1 表3、插入数据4、查看数据5、授予权限创建用户test2以 test 用户登录并授予权限&#xff1a;使用test2用户登录查询&#xff0c;测试结果 1、以 test 用户登录 首先&#xff0c;您需要以 test 用户登录到数据库 sqlplus test/1232…

t-product的matlab实现

t-product是一个比较好的概念&#xff0c;相对应于矩阵中的乘法。 定义如下 这里的 circ(A),MatVec(b) 的定义分别如下 这么定义的原因是为了映射到FFT域里面去&#xff0c;简化计算。 上面的一段摘录说明&#xff1a;直接按照定义来计算&#xff0c;会耗费大量的计算资源。因…

Win通过WSL配置安装Redis

一共分为如下几步&#xff1a; 安装WSL发行版&#xff0c;如Ubuntu安装Redis配置Redis与WSL WSL安装 这里有微软官方的文档&#xff1a;https://learn.microsoft.com/zh-cn/windows/wsl/install 但我不建议零基础的这么做。很容易输完一些命令之后&#xff0c;把环境弄得乱七…

网页开发如何实现简易页面跳动/跳转,html课堂练习/作业,页面ABC的相互跳转

先建一个文件夹&#xff0c;文件夹包含三个文件夹&#xff0c;三个文件夹分别包含各自的代码。(可以只建一个文件夹&#xff0c;文件夹包含各页面代码) 页面1的代码&#xff1a; <head> <meta http-equiv"Content-Type" content"text/html; charsetu…

【原创】java+swing+mysql通讯录管理系统设计与实现

前言&#xff1a; 通讯录管理系统是一个设计和实现个人或组织之间联系人信息管理的系统。该系统可能涵盖了联系人的详细信息&#xff0c;如姓名、电话号码、电子邮件地址、地址等&#xff0c;并提供了对联系人信息进行添加、删除、修改、查询等操作的功能。通讯录管理系统旨在…

FISCOBCOS入门(十)Truffle自定义测试helloworld

在windos终端内安装truffle npm install -g truffle truffle --version 出现上图情况也没问题 下面就可以进行我们的操作了 创建一个文件truffle 创建一个空工程 truffle init 在contracts内加入HelloWorld合约 // SPDX-License-Identifier: MIT pragma solidity ^0.8.0; c…

基于Vue+SpringBoot的天然气工程运维系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目详细录屏 二、功能模块2.1 系统角色分类2.2 核心功能2.2.1 流程 12.2.2 流程 22.3 各角色功能2.3.1 系统管理员功能2.3.2 用户服务部功能2.3.3 分公司&#xff08;施工单位&#xff09;功能2.3.3.1 技术员角色功能2.3.3.2 材料员角色功能 2.3…

Linux发展史与环境安装

Linux发展史与环境安装 一、Linux发展史推动技术进步的基本模式理解操作系统的发展理解Linux操作系统的发展 一、Linux的环境安装 一、Linux发展史 Linux和window XX其实都是一样的&#xff0c;定位&#xff1a;操作系统&#xff0c;企业内部&#xff0c;要给用户提供“互联网…

ping命令使用示例解析

【一】ping命令简介 ping &#xff08;Packet Internet Groper&#xff09;是一种因特网包探索器&#xff0c;用于测试网络连接量的程序。ping的一般用途有&#xff1a; ①【测试网络物理链路是否正常】&#xff1a;通过将ICMP(Internet控制消息协议)回显数据包发送到网络终端&…

Nacos安装指南

Nacos安装指南 1.Windows安装 开发阶段采用单机安装即可。 1.1.下载安装包 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; GitHub主页&#xff1a;https://github.com/alibaba/nacos GitHub的Release下载…

JVM——运行时数据区(堆+方法区+直接内存)

目录 1.Java堆2.方法区**方法区&#xff08;Method Area&#xff09;溢出**方法区&#xff08;Method Area&#xff09;字符串常量池静态变量的存储 3.直接内存(Direct Memory) 1.Java堆 ⚫ 一般Java程序中堆内存是空间最大的一块内存区域。创建出来的对象都存在于堆上。 ⚫ 栈…

leetcode - 串联所有单词的子串 - 最小覆盖子串 - x 的平方根

I30. 串联所有单词的子串 - 力扣&#xff08;LeetCode&#xff09; 给定一个字符串 s 和一个字符串数组 words。 words 中所有字符串 长度相同。 s 中的 串联子串 是指一个包含 words 中所有字符串以任意顺序排列连接起来的子串。 例如&#xff0c;如果 words ["ab&qu…