当前位置: 首页 > news >正文

SpringBoot 实现对提供的接口进行 AES (加密,解密)

业务来源:

       最近工作中,领导要求给别的项目组的小伙伴提供几个接口,要求对接口的参数进行解密操作,然后对返回的数据进行加密操作。

       这时我想到了AES  

       AES 是对称加密算法,优点:加密速度快;缺点:如果秘钥丢失,就容易解密密文,安全性相对比较差。

代码案例:

请求参数格式:

{"appId": "queryLectureListByPage","data": "eIVh49T2zKQrtcrhVi6BXcXljN4XFlZc9csQiyayIE1eYeIatVNc9gOTL6HHYj29arBEV3TXMVnQxGIR2EHMfICQz+Aq5ldGk0ys13Rgiqk="
}

响应的参数格式:

{"code": 200,"message": "ok","data": "eHDl88EzrjfZzA179EN6s1dUPs10bWpSWRo2skyQf1+eO6x66ypDnVXoyB5wr6T62lmfVdwa3oK0ZFqnOzd3SW/DE6UaMPZtJovzFTpjxbzvnuwO3v9b3vEsA2nOUQEjEqbpzBrzEClNtL2tkSuoA7oJkTiH3ec6otwFFJZGbV93JW9+xvFkG3TObHIO6fdqlgNIDGbgs7TnwStc64suuH+H7Bt25pCggCq6yVv+Zx69/0Zprvu5s7Dma8NYy/N69cfWgj+06Ik5DXcJlzlZXKQLwwQHiHtleIum2dSF3HWE7ck212n/zn1WVVpGUFnevYCr7Gx/lHbkh/hIOifl8sDpkaISP2tO4kXDi1neUyCnrM7437rf/ZhLPBANkkIO40cZcjEGdrMNswAfZ6XxkBTBq3BMpnjulUbSPZXA6xwwdiaORv1Jx9yxpVBRuw5D4FHby+VPRAh3WP2VMptpzXYeJGBJXU/KvODrKy+tDb8Iq/PUESzECrrYVc/QwWVeBmNKOFyCtXTB486QWqUGbFvoWHnQUUh/taM8/GOYglWzCtziDntRxum2qruxuq23fnNknKGi3wJBzBSZj8kWw0NUx7RIaZcoqwbzmYx4H6h9D28ViAv/y4/nQGxKho3nlW5EVuk6+yQLadc1DSp4Ug=="
}

生成密钥:

package com.ly.cloud.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import com.alibaba.druid.util.Base64;
import org.apache.commons.codec.binary.Hex;public class AESUtils {private static final String AES = "AES";private static final String UTF8 = "UTF-8";private static final String CIPHERALGORITHM = "AES/ECB/PKCS5Padding";private static final String Key = "9!#95hsup*&$1zq7";public static void main(String[] args) throws IOException {// wqkjejqwkejqwk  可随便输入字符串,生成对应的密钥String wqkjejqwkejqwk = encrypts("wqkjejqwkejqwk");System.out.println(wqkjejqwkejqwk);}/*** 生成base 64 作为AES加密后的密钥*/public static  String encrypts(String content) {try {byte[] encodeFormat = Key.getBytes();SecretKeySpec key = new SecretKeySpec(encodeFormat, AES);// Cipher对象实际完成加密操作Cipher cipher = Cipher.getInstance(CIPHERALGORITHM);// 加密内容进行编码byte[] byteContent = content.getBytes(UTF8);// 用密匙初始化Cipher对象cipher.init(Cipher.ENCRYPT_MODE, key);// 正式执行加密操作byte[] result = cipher.doFinal(byteContent);return Hex.encodeHexString(result);} catch (Exception e) {e.printStackTrace();return null;}}}

思路:

通过传入的appId然后去数据库中查询到对应的 唯一密钥。然后根据唯一密钥进行解析密文。然后转成将密文转成 我们需要的参数对象。

核心代码:
AES加密解密工具类:
package com.ly.cloud.util;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import com.alibaba.druid.util.Base64;
import org.apache.commons.codec.binary.Hex;public class AESUtils {private static final String AES = "AES";private static final String UTF8 = "UTF-8";private static final String CIPHERALGORITHM = "AES/ECB/PKCS5Padding";private static final String Key = "9!#95hsup*&$1zq7";/*** AES加密+Base64转码* * @param data 明文(16进制)* @param key  密钥* @return*/public static String encrypt(String data, String key) {byte[] keyb = null;keyb = Base64.base64ToByteArray(key);SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");Cipher cipher = null;try {cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {e.printStackTrace();}try {cipher.init(Cipher.ENCRYPT_MODE, sKeySpec);} catch (InvalidKeyException e) {e.printStackTrace();}byte[] bjiamihou = null;String miwen = "";try {bjiamihou = cipher.doFinal(data.getBytes("utf-8"));// byte加密后miwen = Base64.byteArrayToBase64(bjiamihou);// 密文用base64加密} catch (IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return miwen;}/*** Base64解码 + AES解码* * @param data 密文 (16进制)* @param key  密钥* @return*/public static String decrypt(String data, String key){byte[] keyb = null;keyb = Base64.base64ToByteArray(key);byte[] miwen = Base64.base64ToByteArray(data);SecretKeySpec sKeySpec = new SecretKeySpec(keyb, "AES");Cipher cipher = null;try {cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {e.printStackTrace();}try {cipher.init(Cipher.DECRYPT_MODE, sKeySpec);} catch (InvalidKeyException e) {e.printStackTrace();}byte[] bjiemihou = null;String mingwen = "";try {bjiemihou = cipher.doFinal(miwen);// byte加密后mingwen = new String(bjiemihou,"utf-8");} catch (IllegalBlockSizeException | BadPaddingException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();}return mingwen;}public static void main(String[] args) throws IOException {String name = "{\"userId\":\"179135\",\"keyword\":\"讲座副标题\",\"pageNum\":\"1\",\"pageSize\":\"10\"}";
//		String encrypt = encrypt(name, "qVkn2qNkkyAAF8PjQL/7GQ==");
//		String name = "{\"userId\":\"179135\",\"pageNum\":\"1\",\"pageSize\":\"20\"}";//		String name1 = "{\"userId\":\"179135\",\"organizerId\":\"02020\"}";String name1 = "{\"pageNum\":\"1\",\"pageSize\":\"20\"}";String encrypt = encrypt(name, "8c5e186c9de8e9a628234522a794f45b0f");System.out.println(encrypt);System.out.println("---------");System.out.println(decrypt(encrypt,"8c5e186c9de8e9a628234522a794f45b0f"));String wqkjejqwkejqwk = encrypts("wqkjejqwkererjqwk");System.out.println(wqkjejqwkererjqwk);}/*** 生成base 64 作为AES加密后的密钥*/public static  String encrypts(String content) {try {byte[] encodeFormat = Key.getBytes();SecretKeySpec key = new SecretKeySpec(encodeFormat, AES);// Cipher对象实际完成加密操作Cipher cipher = Cipher.getInstance(CIPHERALGORITHM);// 加密内容进行编码byte[] byteContent = content.getBytes(UTF8);// 用密匙初始化Cipher对象cipher.init(Cipher.ENCRYPT_MODE, key);// 正式执行加密操作byte[] result = cipher.doFinal(byteContent);return Hex.encodeHexString(result);} catch (Exception e) {e.printStackTrace();return null;}}// 加密 public static String dataToAES(String password,String data){String hexStr = encrypt(data, password);return hexStr;}// 解密public static String AESToData(String password, String data){return decrypt(data, password);}}
业务层核心代码: 
    @Overridepublic String organizerList(LectureEncryptDto encrypt) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {//获取appid 对应的key值String key = checkParam(encrypt);// 解密参数  根据传入不同的 对象返回不同的对象MySubscribeDto subscribe = returnObject(MySubscribeDto.class, key, encrypt);//校验解密后参数是否为空checkPageParam(subscribe, "2");Page<MySubscribe> page = new Page<>(subscribe.getPageNum(), subscribe.getPageSize());PageDto<MySubscribe> pageDto = new PageDto<>();IPage<MySubscribe> pageData = lectureMapper.organizerList(page, subscribe.getUserId());pageDto.setTotal(pageData.getTotal());pageDto.setPages(pageData.getPages());pageDto.setPageSize(subscribe.getPageSize());pageDto.setPageNum(subscribe.getPageNum());pageDto.setList(pageData.getRecords());//加密String json = JSONUtil.toJsonStr(pageDto);return AESUtils.dataToAES(key, json);}/*** 根据传入的不同的对象,将他进行解密。然后返回*/public static <T> T returnObject(Class<T> clazz, String key, LectureEncryptDto dto) {Gson gson = new Gson();String decryptedData = AESUtils.AESToData(key, dto.getData());if (StrUtil.isEmpty(decryptedData)) {throw new BusinessException("appId生成的data密钥有误");}return gson.fromJson(decryptedData, clazz);}/*** 检查appID 是否有效*/public String checkParam(LectureEncryptDto dto) {// 根据他传的appid 去数据库里取出appid 对应的 key值,String key = lectureMapper.getAppIdKey(dto.getAppId());if (StrUtil.isEmpty(key)) {throw new BusinessException("appId有误,请重新输入");}return key;}/*** 检查分页-以及其它所需参数是否为空*/public static void checkPageParam(Object objects, String key) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {Class<?> clazz = objects.getClass();Method getPageSizeMethod = clazz.getMethod("getPageSize");Method getPageNumMethod = clazz.getMethod("getPageNum");Integer pageSize = (Integer) getPageSizeMethod.invoke(objects);Integer pageNum = (Integer) getPageNumMethod.invoke(objects);if (pageSize == null || pageNum == null) {throw new BusinessException("页码不能为空");}// 根据key设置相应的属性switch (key) {case "1":break;case "2":Method userIdMethod = clazz.getMethod("getUserId");if (StrUtil.isEmpty((String) userIdMethod.invoke(objects))) {throw new BusinessException("学工号不能为空");}break;case "3":Method user = clazz.getMethod("getUserId");Method getId = clazz.getMethod("getOrganizerId");if (StrUtil.isEmpty((String) user.invoke(objects)) && StrUtil.isEmpty((String) getId.invoke(objects))) {throw new BusinessException("学工号或主办单位ID不能为空");}}}

相关文章:

SpringBoot 实现对提供的接口进行 AES (加密,解密)

业务来源&#xff1a; 最近工作中&#xff0c;领导要求给别的项目组的小伙伴提供几个接口&#xff0c;要求对接口的参数进行解密操作&#xff0c;然后对返回的数据进行加密操作。 这时我想到了AES AES 是对称加密算法&#xff0c;优点&#xff1a;加密速度快&#xff1b;缺点…...

ASP.NET学生成绩管理系统

摘要 本系统依据开发要求主要应用于教育系统&#xff0c;完成对日常的教育工作中学生成绩档案的数字化管理。开发本系统可使学院教职员工减轻工作压力&#xff0c;比较系统地对教务、教学上的各项服务和信息进行管理&#xff0c;同时&#xff0c;可以减少劳动力的使用&#xf…...

谁考了第k名C++

题目描述 在一次考试中&#xff0c;每个学生的成绩都不相同&#xff0c;现知道了每个学生的学号和成绩&#xff0c;求考第k名学生的学号和成绩。&#xff08;按成绩从大到小排列&#xff09; 输入 第一行有两个整数&#xff0c;分别是学生的人数n&#xff08;1≤n≤100&…...

多线服务器的优势有哪些?

服务器中包含着多线服务器、双线服务器和单线服务器等&#xff0c;其中多线服务器可以支持多个IP地址&#xff0c;今天小编就来带领大家一些来了解一下多线服务器的优势有哪些吧&#xff01; 多线服务器是在一个互联网数据中心&#xff0c;通过特殊的技术手段将不同的多家网络接…...

vue + element-plus 开发中遇到的问题

1.问题之路由守卫 初写路由守卫&#xff0c;对于next()的理解不是很透彻&#xff0c;就想着都放行&#xff0c;不然看不到效果&#xff0c;结果控制台出现了警告&#xff0c;想着报黄的问题就不是问题&#xff0c;但仔细一看发现他说&#xff0c;如果再生产阶段就会失败&#x…...

使用java远程提交flink任务到yarn集群

使用java远程提交flink任务到yarn集群 背景 由于业务需要&#xff0c;使用命令行的方式提交flink任务比较麻烦&#xff0c;要么将后端任务部署到大数据集群&#xff0c;要么弄一个提交机&#xff0c;感觉都不是很离线。经过一些调研&#xff0c;发现可以实现远程的任务发布。…...

麻了!新增4.1分,CCF-C类,2区毕业神刊,被标记On Hold!

本周投稿推荐 SSCI • 2区社科类&#xff0c;3.0-4.0&#xff08;社科均可&#xff09; EI • 计算机工程类&#xff08;接收广&#xff0c;录用极快&#xff09; SCI&EI • 4区生物医学类&#xff0c;1.5-2.0&#xff08;录用率99%&#xff09; • 1区工程类&#…...

tomcat 的启动流程

tomcat 的启动流程 中 使用的Lifecycle 生命流程 。在这里还使用了设计模式中的模板模式&#xff08;LifecycleBase 是一个模板类&#xff09; init&#xff08;&#xff09;方法 start() 方法 container 的处理...

YOLOv9全网最新改进系列::YOLOv9完美融合双卷积核(DualConv)来构建轻量级深度神经网络,目标检测模型有效涨点神器!!!

YOLOv9全网最新改进系列&#xff1a;&#xff1a;YOLOv9完美融合双卷积核&#xff08;DualConv&#xff09;来构建轻量级深度神经网络,目标检测模型有效涨点神器&#xff01;&#xff01;&#xff01; YOLOv9原文链接戳这里&#xff0c;原文全文翻译请关注B站Ai学术叫叫首er …...

PCIE协议-2-事务层规范-MEM/IO/CFG request rules

2.2.7 内存、I/O和配置请求规则 以下规则适用于所有内存、I/O和配置请求。每种类型的请求还有特定的额外规则。 所有内存、I/O和配置请求除了常见的头标字段外&#xff0c;还包括以下字段&#xff1a;requester ID[15:0]和Tag[9:0]&#xff0c;形成事务ID。Last DW BE[3:0] a…...

jmeter分布式集群压测

目的&#xff1a;通过多台机器同时运行 性能压测 脚本&#xff0c;模拟更好的并发压力 简单点&#xff1a;就是一个人&#xff08;控制机controler/调度机 master&#xff09;做一个项目的时候&#xff0c;压力有点大&#xff0c;会导致结果不理想&#xff0c;这时候找几个人&a…...

美国加州正测试ChatGPT等生成式AI,在4大部门应用

5月11日&#xff0c;美联社消息&#xff0c;美国加州政府正在测试ChatGPT等生成式AI&#xff0c;应用在税收和收费管理部、交通部、公共卫生部以及卫生与公众服务部4大部门。 测试时间6个月&#xff0c;为其提供技术支持的一共有5家公司&#xff0c;分别是OpenAI、Anthropic、…...

【Kali Linux工具篇】wpscan的基本介绍与使用

介绍 WPScan是Kali Linux默认自带的一款漏洞扫描工具&#xff0c;它采用Ruby编写&#xff0c;能够扫描WordPress网站中的多种安全漏洞&#xff0c;其中包括主题漏洞、插件漏洞和WordPress本身的漏洞。最新版本WPScan的数据库中包含超过18000种插件漏洞和2600种主题漏洞&#x…...

C#算法之计数排序

算法释义&#xff1a;计数排序是一种非基于比较的排序算法&#xff0c;它不依赖于比较操作来确定元素的顺序&#xff0c;而是通过键值索引直接确定元素的输出位置。计数排序适用于一定范围内的整数排序。为什么说是一定范围之内呢&#xff1f;原因如下&#xff1a;计数排序的复…...

EasyExcel简单使用

EasyExcel简单使用 ​ 之前一直用的Apache POI来做数据的导入导出&#xff0c;但听说阿里的EasyExcel也拥有POI的功能的同时&#xff0c;在处理大数据量的导入导出的时候性能上比POI更好&#xff0c;所以就来尝试使用一下 导入Maven依赖&#xff1a; <dependency><…...

Notes客户端中的漫游功能

大家好&#xff0c;才是真的好。 故事&#xff0c;首先是从一个小图标开始的&#xff0c;很多人问我Domino公共通讯录中&#xff0c;个人文档前面有一个绿色小球图标&#xff0c;这是什么意思&#xff1f; 我的答案&#xff1a;这是Notes客户端中的漫游功能。 说到漫游&…...

为什么要内存对齐?

首先&#xff0c;我们介绍一下结构体内存对齐的规则&#xff1a; 1.第一个成员在与结构体偏移量为0的地址处。 2.其他成员变量要对其到某个数字&#xff08;对齐数&#xff09;的整数倍的地址处。 注&#xff1a;对齐数编译器默认的一个对齐数与该成员大小的较小值&#xff…...

23、Flink 的 Savepoints 详解

Savepoints 1.什么是 Savepoints Savepoint 是依据 Flink checkpointing 机制所创建的流作业执行状态的镜像&#xff0c;可以使用 Savepoint 进行 Flink 作业的停止、重启或更新。 Savepoint 由两部分组成&#xff1a;稳定存储&#xff08;例如 HDFS&#xff0c;S3&#xff…...

【Unity】Unity项目转抖音小游戏(二)云数据库和云函数

业务需求&#xff0c;开始接触一下抖音小游戏相关的内容&#xff0c;开发过程中记录一下流程。 抖音云官方文档&#xff1a;https://developer.open-douyin.com/docs/resource/zh-CN/developer/tools/cloud/develop-guide/cloud-function-debug 1.开通抖音云环境 抖音云地址&a…...

SpringBoot集成jasypt对yml文件指定参数加密并自定义@bean隐藏密钥

1、查看SpringBoot和jasypt对应版本。 Jasypt 1.9.x 通常与 Spring Boot 1.5.x 相对应。 Jasypt 2.1.x 通常与 Spring Boot 2.0.x 相对应。 Jasypt 3.x 通常与 Spring Boot 2.1.x相对应。 2、引入maven <dependency><groupId>com.github.ulisesbocchio</groupI…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

K8S认证|CKS题库+答案| 11. AppArmor

目录 11. AppArmor 免费获取并激活 CKA_v1.31_模拟系统 题目 开始操作&#xff1a; 1&#xff09;、切换集群 2&#xff09;、切换节点 3&#xff09;、切换到 apparmor 的目录 4&#xff09;、执行 apparmor 策略模块 5&#xff09;、修改 pod 文件 6&#xff09;、…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

Frozen-Flask :将 Flask 应用“冻结”为静态文件

Frozen-Flask 是一个用于将 Flask 应用“冻结”为静态文件的 Python 扩展。它的核心用途是&#xff1a;将一个 Flask Web 应用生成成纯静态 HTML 文件&#xff0c;从而可以部署到静态网站托管服务上&#xff0c;如 GitHub Pages、Netlify 或任何支持静态文件的网站服务器。 &am…...

spring:实例工厂方法获取bean

spring处理使用静态工厂方法获取bean实例&#xff0c;也可以通过实例工厂方法获取bean实例。 实例工厂方法步骤如下&#xff1a; 定义实例工厂类&#xff08;Java代码&#xff09;&#xff0c;定义实例工厂&#xff08;xml&#xff09;&#xff0c;定义调用实例工厂&#xff…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

安全突围:重塑内生安全体系:齐向东在2025年BCS大会的演讲

文章目录 前言第一部分&#xff1a;体系力量是突围之钥第一重困境是体系思想落地不畅。第二重困境是大小体系融合瓶颈。第三重困境是“小体系”运营梗阻。 第二部分&#xff1a;体系矛盾是突围之障一是数据孤岛的障碍。二是投入不足的障碍。三是新旧兼容难的障碍。 第三部分&am…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...