aes加密字符串c++_springboot2.2.X手册:防抓包?快速实现API接口数据加密

溪云阁:专注编程教学,架构,JAVA,Python,微服务,机器学习等,欢迎关注

上一篇:springboot2.2.X手册:redis的7种类型100个方法全解析

有没有遇到这样子的接口,放到互联网上面去,谁都可以调用,谁都可以访问,完全就是公开的,这样子的接口,如果只是普通的数据,其实可以考虑,只是可以考虑,但是,一般情况下,我们是不允许这样子做的。

975099973736543e576bc5b18362da03.png

接口安全防什么

1、防止恶意调用攻击

2、防止篡改信息攻击

3、防拦截攻击,数据被截取后进行修改后重新放回去

4、防止数据泄漏攻击

edd5a863f36a0e644308de54ef9789d2.png

什么是抓包

抓包(packet capture)就是将网络传输发送与接收的数据包进行截获、重发、编辑、转存等操作,也用来检查网络安全。抓包也经常被用来进行数据截取等。

这是百度百科给我们的解释,当我们一些放到互联网上的数据,直接采用明文的话,就很容易被抓包,然后进行修改或者被恶意植入木马,这是比较恶心的行为,今天我们就来研究一下怎么样对接口进行数据加密。

db2032479a0eaba2b4326ef170495176.png

POM文件

         org.springframework.boot            spring-boot-starter-web        org.springframework.boot            spring-boot-autoconfigure        com.bootsmodule-boots-api2.0.0.RELEASE

编写加密解密工具类

/** * All rights Reserved, Designed By 林溪 * Copyright:    Copyright(C) 2016-2020 * Company       溪云阁 . */package com.module.boots.api.de.utils;import java.security.NoSuchAlgorithmException;import java.security.SecureRandom;import javax.crypto.Cipher;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.SecretKeySpec;import org.apache.tomcat.util.codec.binary.Base64;import com.module.boots.exception.CommonRuntimeException;/** * AES加密解密 * @author:溪云阁 * @date:2020年6月4日 */public class AesUtils {    private static final String KEY_ALGORITHM = "AES";    private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";// 默认的加密算法    /**     * AES 加密操作     * @author 溪云阁     * @param content 待加密内容     * @param password 加密密码     * @return String 返回Base64转码后的加密数据     */    public static String encrypt(String content, String password) {        try {            // 创建密码器            final Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);            // 设置为UTF-8编码            final byte[] byteContent = content.getBytes("utf-8");            // 初始化为加密模式的密码器            cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(password));            // 加密            final byte[] result = cipher.doFinal(byteContent);            // 通过Base64转码返回            return Base64.encodeBase64String(result);        }        catch (final Exception ex) {            throw new CommonRuntimeException(ex.fillInStackTrace());        }    }    /**     * AES 解密操作     * @author 溪云阁     * @param content     * @param password     * @return String     */    public static String decrypt(String content, String password) {        try {            // 实例化            final Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM);            // 使用密钥初始化,设置为解密模式            cipher.init(Cipher.DECRYPT_MODE, getSecretKey(password));            // 执行操作            final byte[] result = cipher.doFinal(Base64.decodeBase64(content));            // 采用UTF-8编码转化为字符串            return new String(result, "utf-8");        }        catch (final Exception ex) {            throw new CommonRuntimeException(ex.fillInStackTrace());        }    }    /**     * 生成加密秘钥     * @author 溪云阁     * @param password 加密的密码     * @return SecretKeySpec     */    private static SecretKeySpec getSecretKey(final String password) {        // 返回生成指定算法密钥生成器的 KeyGenerator 对象        KeyGenerator kg = null;        try {            kg = KeyGenerator.getInstance(KEY_ALGORITHM);            // AES 要求密钥长度为 128            kg.init(128, new SecureRandom(password.getBytes()));            // 生成一个密钥            final SecretKey secretKey = kg.generateKey();            // 转换为AES专用密钥            return new SecretKeySpec(secretKey.getEncoded(), KEY_ALGORITHM);        }        catch (final NoSuchAlgorithmException ex) {            throw new CommonRuntimeException(ex.fillInStackTrace());        }    }    public static void main(String[] args) {        final String str = "V9JofCHn02eyXRiDb1VuseRSuOgEQftROwudMPWwMAO2Wk5K7aYZ4Vtm6xiTn5i5";        System.out.println(decrypt(str, "xy934yrn9342u0ry4br8cn-9u2"));    }}

编写加密注解

/** * All rights Reserved, Designed By 林溪 * Copyright:    Copyright(C) 2016-2020 * Company       溪云阁 . */package com.module.boots.api.de;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** * 返回对body加密,针对类跟方法 * @author:溪云阁 * @date:2020年6月4日 */@Target({ ElementType.METHOD, ElementType.TYPE })@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface ResponseEncrypt {    /**     * 返回对body加密,默认是true     * @author 溪云阁     * @return boolean     */    boolean value() default true;}

编写加密判断类

/** * All rights Reserved, Designed By 林溪 * Copyright:    Copyright(C) 2016-2020 * Company       溪云阁 . */package com.module.boots.api.de;import org.springframework.core.MethodParameter;/** * 是否需要加密解密 * @author:溪云阁 * @date:2020年6月4日 */public class NeedDe {    /**     * 判断是否需要加密     * @author 溪云阁     * @param returnType     * @return boolean     */    public static boolean needEncrypt(MethodParameter returnType) {        boolean encrypt = false;        // 获取类上的注解        final boolean classPresentAnno = returnType.getContainingClass().isAnnotationPresent(ResponseEncrypt.class);        // 获取方法上的注解        final boolean methodPresentAnno = returnType.getMethod().isAnnotationPresent(ResponseEncrypt.class);        if (classPresentAnno) {            // 类上标注的是否需要加密            encrypt = returnType.getContainingClass().getAnnotation(ResponseEncrypt.class).value();            // 类不加密,所有都不加密            if (!encrypt) {                return false;            }        }        if (methodPresentAnno) {            // 方法上标注的是否需要加密            encrypt = returnType.getMethod().getAnnotation(ResponseEncrypt.class).value();        }        return encrypt;    }}

编写加密拦截

/** * All rights Reserved, Designed By 林溪 * Copyright:    Copyright(C) 2016-2020 * Company       溪云阁 . */package com.module.boots.api.de;import org.springframework.beans.factory.annotation.Value;import org.springframework.core.MethodParameter;import org.springframework.http.MediaType;import org.springframework.http.converter.HttpMessageConverter;import org.springframework.http.server.ServerHttpRequest;import org.springframework.http.server.ServerHttpResponse;import org.springframework.web.bind.annotation.ControllerAdvice;import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;import com.module.boots.api.de.utils.AesUtils;import com.module.boots.api.message.ResponseMsg;/** * 对接口数据进行加密 * @author:溪云阁 * @date:2020年6月4日 */@ControllerAdvicepublic class ResponseEncryptAdvice implements ResponseBodyAdvice {    @Value("${module.boots.response.aes.key}")    private String key;    @Override    public boolean supports(MethodParameter returnType, Class extends HttpMessageConverter>> converterType) {        return true;    }    /**     * 在写入之前更改body的值     * @author 溪云阁     * @param body     * @param returnType     * @param selectedContentType     * @param selectedConverterType     * @param request     * @param response     * @return     * @return     */    @SuppressWarnings({ "unchecked", "rawtypes" })    @Override    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,            Class extends HttpMessageConverter>> selectedConverterType, ServerHttpRequest request,            ServerHttpResponse response) {        // 判断是否需要加密        final boolean encrypt = NeedDe.needEncrypt(returnType);        if (!encrypt) {            return body;        } else {            // 如果body是属于ResponseMsg类型,只需要对data里面的数据进行加密即可            if (body instanceof ResponseMsg) {                final ResponseMsg responseMsg = (ResponseMsg) body;                final Object data = responseMsg.getData();                if (data == null) {                    return body;                } else {                    responseMsg.setData(AesUtils.encrypt(data.toString(), key));                    return responseMsg;                }            } else {                return body;            }        }    }}

加入密钥

# aes的密钥module.boots.response.aes.key: xy934yrn9342u0ry4br8cn-9u2

编写加密解密接口

/** * All rights Reserved, Designed By 林溪 * Copyright:    Copyright(C) 2016-2020 * Company       溪云阁 . */package com.boots.api.de.view.de.view;import org.springframework.beans.factory.annotation.Value;import org.springframework.http.MediaType;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;import com.boots.api.de.view.de.vo.GetEncryptVO;import com.module.boots.api.de.ResponseEncrypt;import com.module.boots.api.de.utils.AesUtils;import com.module.boots.api.message.ResponseMsg;import com.module.boots.api.utils.MsgUtils;import com.module.boots.exception.CommonRuntimeException;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import lombok.SneakyThrows;/** * 加密数据接口 * @author:溪云阁 * @date:2020年6月4日 */@SuppressWarnings("deprecation")@Api(tags = { "web服务:加密数据接口" })@RestController@RequestMapping("view/deView")public class DeView {    @Value("${module.boots.response.aes.key}")    private String key;    /**     * 获取加密数据     * @author 溪云阁     * @return ResponseMsg     */    @ApiOperation(value = "获取加密数据")    @GetMapping(value = "/getEncrypt", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)    @SneakyThrows(CommonRuntimeException.class)    @ResponseEncrypt    public ResponseMsg getEncrypt() {        final GetEncryptVO vo = new GetEncryptVO();        vo.setId("b037123c");        vo.setUserName("xnwqr98urx");        return MsgUtils.buildSuccessMsg(vo);    }    /**     * 获取解密数据     * @author 溪云阁     * @return ResponseMsg     */    @ApiOperation(value = "获取解密数据")    @GetMapping(value = "/getDecrypt", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)    @SneakyThrows(CommonRuntimeException.class)    public ResponseMsg getDecrypt(@RequestParam(value = "content") String content) {        final String str = AesUtils.decrypt(content, key);        return MsgUtils.buildSuccessMsg(str);    }}

测试

6a2e30724808ef72f20a36e8e8f6fa13.png
9c205a524b8e116e3585b9e0c8260ff0.png

从实验的结果上看,我们在获取数据的时候,直接对data里面的数据进行了加密,这种加密方式只有我们自己可以破解,放到网上去,即使只有密钥,也破解不了。

这里只做接口的数据的加密,生产中经常需要加入token,时间戳等进行验证,各位同学自行拓展即可。

--END--

作者:@溪云阁

原创作品,抄袭必究,转载注明出处

如需要源码,转发,关注后私信我

部分图片或代码来源网络,如侵权请联系删除,谢谢!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

鸿蒙系统打造完备终端,搭载鸿蒙系统的手机很快推出,华为生态更加完善

2019年的8月9日,在华为开发者大会上华为向大家正式的发布了一款操作系统——鸿蒙系统。这个系统备受大家的关注,鸿蒙2.0的发布也在时刻期待中。因为在目前的操作系统中,华为的鸿蒙操作系统是仅次于安卓、ios的存在,而今日&#xf…

python给图片加半透明水印_Python 批量加水印就这么简单!

工作的时候,尤其是自媒体,我们必备水印添加工具以保护我们的知识产权,网上有许多的在线/下载的水印添加工具,但他们或多或少都存在以下问题: 在线工具需要将图片上传到对方服务器,信息不安全。 很多工具不具备批量处理…

html 选中状态,html默认选中状态

html中标签用法解析及如何设置selec标签定义和用法 select 元素可创建单选或多选菜单。当提交表单时,浏览器会提交选定的项目,或者收集用逗号分隔的多个选项,将其合成一个单独的参数列表,并且在将 表单数据提交给服务器时包括 nam…

wxpython制作表格界面_[Python] wxPython 菜单栏控件学习总结(原创)

1、总结 1、大体创建过程 1、创建一个 菜单栏 : menuBar wx.MenuBar()相当于这个白色地方,没有File这个菜单 2、创建 菜单 : fileMenu wx.Menu()这两个不是直接“用的”,叫菜单。既用来分类其他 菜单项 的文件夹样 3、创建 菜单项 : newItem wx.MenuI…

android 8三星note8,信息太多很烦琐?告诉你三星Note8有妙招

不知从何时开始,我们眼前的信息变得丰富而繁杂。简洁的新闻无需经过报纸过滤,发生数分钟已经城皆知。预测晴雨也无需依靠天气先生,点亮手机即可洞悉风雨。生活在信息时代的我们仅用几英寸的窗口观察世界,信息的洪流难免会遮蔽眼前…

python做excel表格教程视频_基于Python实现excel表格读写

首先安装对应的xlrd和xlwt 打开cmd命令窗口输入pip install xlrd和pip install xlwt就可以安装。之后输入pip list检查是否成功配置:xlrd操作# 接下来就是常用的语法操作: excel_data xlrd.open_workbook(文件路径)#得到对应的工作表 sheet excel_data…

虚无鸿蒙哪个厉害,【图说鸿蒙】鸿蒙设定之七柱神(五)

原标题:【图说鸿蒙】鸿蒙设定之七柱神(五)七柱神玄冥神飞来流去本无心,无空无我混天尘。幻作人形深简出,不是老妪是海神。玄冥神 虚无荒海司掌海洋、流动之力 神威之色为蓝执掌海洋、流动之力的神,是神道“熵”的最高掌控者&#…

java lambda 排序_Java8特性:Lambda表达式之概念篇

Java自诞生已经有十几个年头了,目前也已经发布了第十三个大版本,其中Java8是常用的版本中最新的一个版本。而Java8最大的特性就是:Lambda表达式、函数式接口和Stream流。本篇我只介绍Lamda表达式的概念以及简单使用,至于别的我打算…

jq获取表格里的checkbox_Python抓取网页表格(一)

Python有很多包可以抓取数据,如selenium、requests、scrapy、pandas,每个包都有其适用性,个人认为在抓取数据时,代码简洁性和数据获取的准确性是需要考虑的因素,时间快慢倒不用太在意,毕竟用python抓数据本…

html一个空格多少像素,一个空格占几个字符?

一个空格通常占2个字符,但有些特殊情况占用3个字符。在程序中,空格占用的字符数取决于程序使用的字符集,如:1、使用多字节字符集时,半角空格占用1个字节,全角空格占用2个字节。2、使用Unicode字符集时&…

各种抠图动态图片_不用手。自动、智能抠图,图片去背景

BgEraser 是一款基于 AI 的自动、智能图片去背景工具,无需勾选可用、可删除区域,上传图片,立即下载即扣图完成的图片。AppinnBgEraser 真是懒人的福音。在此之前,比如很好用的在线去背景服务 remove.bg,是需要用户手动…

bigdecimal 保留两位小数_Python的保留小数及对齐

Python的保留小数:方法1:用round函数(有坑)。median 12.3004886print(round(median, 2)) # 保留两位小数print(round(median, 3)) # 保留三位小数print(round(median, 4)) # 保留四位小数运行结果:12.312.312.3005可以看出Python中的r…

分布式光伏补贴_四川:2020年起工商业分布式光伏已无补贴

来源:四川省发改委日前,四川省发改委发布《四川省分布式光伏建设管理相关政策》,对该省分布式光伏发电项目定义、分类、备案程序、需要国补的项目相关政策进行了梳理。值得注意的是,文件明确,自2020年起,四…

用计算机玩游戏最简单的方法,如何制作电脑简易命令小游戏

满意答案sylvia10172019.01.20采纳率:48% 等级:7已帮助:460人简单的Dos小游戏开始学习java,这周只简单的学习了C的基本语法:输入输出,判断循环,因此用这些东西在java上瞎写了一个DOS小游戏。…

pandas filter_数据分析之Pandas操作(2)

接着数据分析之Pandas操作(1)的介绍,本次介绍在实际应用场景中几个常用的函数。还是以titanic生存数据为例,本次需要导入pandas 、numpy 、scipy三个工具包。import pandas as pdimport numpy as npfrom scipy.stats import zscoretrain_data pd.read_c…

ios 隐藏app的插件_等了5年终于复活,iPhone上最干净好用的微博App

来,先跟小虎妞一起回忆下2013年的微博客户端。(图源水印)那时候,首页还是按时间顺序来的,也没有赴美产子、老爷夫人知道错了的广告。后来,随着微博一次次改版,客户端越来越臃肿,第三方微博客户端像雨后春笋…

python调用node_在node中执行python脚本

Node.js多进程基础 Node.js 是以单线程的模式运行的,但它使用的是事件驱动来处理并发。这样有助于我们在多核 cpu 的系统上创建多个子进程,从而提高性能。 每个子进程总是带有三个流对象:child.stdin, child.stdout 和child.stderr。他们可能…

docker配置 nacos_Nacos - 阿里开源配置中心

这里是喵了个咪的后端技术分享,觉得写的不错。点个赞,转发一下,关注一下。本文载于个人原创技术博客http://w-blog.cn,转载请注明出处,非法转载抄袭将追究其责任。配置中心相信大家都有听过,zookeeper、apo…

jdbc获取mysql第二行表信息_【奇技淫巧】MySQL另类方法获取元数据信息

问:在进行MySQL注入时,我们通常是通过information_schema元数据来获取表名、字段名信息,从而读取相应数据。但是如果waf或其它过滤了information_schema关键字,那么还有什么方法可以读取元数据信息呢?答:从…

vscode使用sass_推荐7 个 极好用的VS Code 插件

你知道将高级开发人员与普通开发人员区分的条件是什么吗?没错,是所使用的工具,俗话说,"工欲善其事必先利其器", 拥有正确的工作工具可以让开发人员的生活变得更加轻松,甚至想写一辈子代码。巧的的…