1:创建加解密注解注解(对于拦截路径上全部采用数据加解密处理,如果有部分接口不需要加解密处理的话,在方法上或者类上加上此注解即可不做加解密处理)

package com.hars.common.infrastructure.validation.security;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;/*** 加解密注解** @author Huangbigao* @date 2020/8/29 11:02*/
@Documented
@Target({ElementType.METHOD, ElementType.TYPE,})
@Retention(RetentionPolicy.RUNTIME)
public @interface CryptoDecryptionSecurity {/*** 是否加解密,默认加解密** @return*/boolean cryptoDecryption() default true;/*** 是否进行request 解密,默认进行解密** @return*/boolean requestDecryption() default true;/*** 是否对输出结果进行加密,默认进行加密** @return*/boolean responseCrypto() default true;
}

ps:注解使用

     @CryptoDecryptionSecurity(responseCrypto = false)@ApiOperation(value = "微信公众号验证业务处理接口")@GetMapping(value = "/handle/{appid}", produces = "text/plain;charset=utf-8")public String authHandle(@PathVariable String appid,@RequestParam(name = "signature", required = false) String signature,@RequestParam(name = "timestamp", required = false) String timestamp,@RequestParam(name = "nonce", required = false) String nonce,@RequestParam(name = "echostr", required = false) String echostr,HttpServletRequest request) {return weChatMpService.authHandle(appid, signature, timestamp, nonce, echostr, request);}

2:创建request解密类

package com.hars.common.infrastructure.utils.filter;import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.hars.common.infrastructure.utils.aes.AesUtil;
import com.hars.common.infrastructure.utils.http.HttpContextUtil;
import com.hars.common.infrastructure.utils.string.StringUtil;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import org.springframework.util.Assert;/*** @author Huangbigao* @date 2020/8/29 10:12*/
public class DecryptionRequestUtil extends HttpServletRequestWrapper {private static final String APPLICATION_JSON = "application/json";/*** 所有参数的Map集合*/private Map<String, String[]> parameterMap;/*** 输入流*/private InputStream inputStream;private final boolean valueValid = true;public DecryptionRequestUtil(HttpServletRequest request, String password) {super(request);String encrypt;String contentType = request.getHeader("Content-Type");if (contentType != null && contentType.contains(APPLICATION_JSON)) {//jsonString bodyStr = HttpContextUtil.getBodyString(request);if (StringUtil.isBlank(bodyStr)){return;}encrypt = (String) JSON.parseObject(bodyStr).get("encrypt");} else {// urlencrypt = request.getParameter("encrypt");}String jsonData = AesUtil.decrypt(encrypt, password);if (StringUtil.isBlank(jsonData)){return;}if (contentType != null && contentType.contains(APPLICATION_JSON)) {if (this.inputStream == null) {this.inputStream = new DecryptionInputStream(new ByteArrayInputStream(jsonData.getBytes()));}}parameterMap = buildParams(jsonData);}private Map<String, String[]> buildParams(String src) {Map<String, String[]> map = new HashMap<>();Map<String, String> params = JSONObject.parseObject(src, new TypeReference<Map<String, String>>() {});for (String key : params.keySet()) {map.put(key, new String[]{params.get(key)});}return map;}@Overridepublic String getParameter(String name) {String[] values = getParameterMap().get(name);if (valueValid){if (values != null) {return (values.length > 0 ? values[0] : null);}return super.getParameter(name);}else {return (values.length > 0 ? values[0] : null);}}@Overridepublic String[] getParameterValues(String name) {String[] values = getParameterMap().get(name);if (valueValid){if (values != null) {return values;}return super.getParameterValues(name);}else {return values;}}@Overridepublic Enumeration<String> getParameterNames() {Map<String, String[]> multipartParameters = getParameterMap();if (valueValid){if (multipartParameters.isEmpty()) {return super.getParameterNames();}}else {if (multipartParameters.isEmpty()) {return null;}}Set<String> paramNames = new LinkedHashSet<>();Enumeration<String> paramEnum = super.getParameterNames();while (paramEnum.hasMoreElements()) {paramNames.add(paramEnum.nextElement());}paramNames.addAll(multipartParameters.keySet());return Collections.enumeration(paramNames);}@Overridepublic Map<String, String[]> getParameterMap() {if (valueValid){return parameterMap == null ? super.getParameterMap() : parameterMap;}else {return parameterMap == null ? new HashMap<>() : parameterMap;}}@Overridepublic ServletInputStream getInputStream() throws IOException {if (valueValid){return this.inputStream == null ? super.getInputStream() : (ServletInputStream) this.inputStream;}else {return this.inputStream == null ? null : (ServletInputStream) this.inputStream;}}/*** 自定义ServletInputStream*/private class DecryptionInputStream extends ServletInputStream {private final InputStream sourceStream;/*** Create a DelegatingServletInputStream for the given source stream.** @param sourceStream the source stream (never {@code null})*/public DecryptionInputStream(InputStream sourceStream) {Assert.notNull(sourceStream, "Source InputStream must not be null");this.sourceStream = sourceStream;}@Overridepublic int read() throws IOException {return this.sourceStream.read();}@Overridepublic void close() throws IOException {super.close();this.sourceStream.close();}@Overridepublic boolean isFinished() {return false;}@Overridepublic boolean isReady() {return false;}@Overridepublic void setReadListener(ReadListener readListener) {}}
}

3:创建response加密类

package com.hars.common.infrastructure.utils.filter;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;/*** @author Huangbigao* @date 2020/8/29 13:11*/
public class ResponseWrapperUtil extends HttpServletResponseWrapper {private ByteArrayOutputStream buffer;private ServletOutputStream out;public ResponseWrapperUtil(HttpServletResponse httpServletResponse) {super(httpServletResponse);buffer = new ByteArrayOutputStream();out = new WrapperOutputStream(buffer);}@Overridepublic ServletOutputStream getOutputStream() throws IOException {return out;}@Overridepublic void flushBuffer() throws IOException {if (out != null) {out.flush();}}public byte[] getContent() throws IOException {flushBuffer();return buffer.toByteArray();}private static class WrapperOutputStream extends ServletOutputStream {private ByteArrayOutputStream bos;WrapperOutputStream(ByteArrayOutputStream bos) {this.bos = bos;}@Overridepublic void write(int b)throws IOException {bos.write(b);}@Overridepublic boolean isReady() {// TODO Auto-generated method stubreturn false;}@Overridepublic void setWriteListener(WriteListener arg0) {// TODO Auto-generated method stub}}
}

5:创建AES加密工具类

package com.hars.common.infrastructure.utils.aes;import com.hars.common.infrastructure.utils.string.StringUtil;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import lombok.extern.slf4j.Slf4j;/*** AES 加解密 工具类** @author Huangbigao* @date 2020/8/28 15:17*/
@Slf4j
public class AesUtil {/*** AES解密** @param content  密文* @param password 秘钥,必须为16个字符组成* @return 明文*/public static String decrypt(String content, String password) {try {if (StringUtil.isBlank(content) || StringUtil.isBlank(password)) {return null;}byte[] encryptByte = Base64.getDecoder().decode(content);Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(password.getBytes(), "AES"));byte[] decryptBytes = cipher.doFinal(encryptByte);return new String(decryptBytes);} catch (Exception e) {log.error(e.getMessage(), e);return null;}}/*** AES加密** @param content  明文* @param password 秘钥,必须为16个字符组成* @return 密文*/public static String encrypt(String content, String password) {try {if (StringUtil.isBlank(content) || StringUtil.isBlank(password)) {return null;}Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(password.getBytes(), "AES"));byte[] encryptStr = cipher.doFinal(content.getBytes(StandardCharsets.UTF_8));return Base64.getEncoder().encodeToString(encryptStr);} catch (Exception e) {log.error(e.getMessage(), e);return null;}}

6:创建加解密Filter类

package com.hars.user.infrastructure.filter;import com.alibaba.fastjson.JSON;
import com.hars.common.infrastructure.utils.aes.AesUtil;
import com.hars.common.infrastructure.utils.filter.DecryptionRequestUtil;
import com.hars.common.infrastructure.utils.filter.ResponseWrapperUtil;
import com.hars.common.infrastructure.validation.security.CryptoDecryptionSecurity;
import com.hars.result.infrastructure.advice.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerExecutionChain;
import org.springframework.web.servlet.HandlerMapping;/*** @author Huangbigao* @date 2020/8/28 16:26*/
public class CryptoDecryptionFilter implements Filter {//方法映射集private List<HandlerMapping> handlerMappings;public CryptoDecryptionFilter(ApplicationContext applicationContext) {Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext,HandlerMapping.class, true, false);if (!matchingBeans.isEmpty()) {this.handlerMappings = new ArrayList<>(matchingBeans.values());AnnotationAwareOrderComparator.sort(this.handlerMappings);}}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest httpServletRequest = (HttpServletRequest) request;HttpServletResponse httpServletResponse = (HttpServletResponse) response;//判断方法上是否存在注解,如果不存在,默认加解密//类上的注解CryptoDecryptionSecurity classFlag = null;//方法上的注解CryptoDecryptionSecurity methodFlag = null;try {HandlerExecutionChain handlerExecutionChain = getHandler(httpServletRequest);Object handler = handlerExecutionChain != null ? handlerExecutionChain.getHandler() : null;if (handler instanceof HandlerMethod) {HandlerMethod method = (HandlerMethod) handler;classFlag = method.getBeanType().getAnnotation(CryptoDecryptionSecurity.class);methodFlag = method.getMethodAnnotation(CryptoDecryptionSecurity.class);//如果方法注解存在,且不加密,则直接返回if (methodFlag != null && !methodFlag.cryptoDecryption()) {chain.doFilter(request, response);return;}//如果类注解存在,且不加密,则直接返回if (classFlag != null && !classFlag.cryptoDecryption()) {chain.doFilter(request, response);return;}}} catch (Exception e) {response.setContentType("application/json; charset=UTF-8");response.getWriter().write(JSON.toJSONString(Response.error("该请求无效", 601)));return;}CryptoDecryptionSecurity currentFlag = null;if (methodFlag != null) {currentFlag = methodFlag;} else if (classFlag != null) {currentFlag = classFlag;}//加解密密码String password = "Hbg584782648!@hb";ResponseWrapperUtil responseWrapper = null;//加解密处理if (currentFlag == null || (currentFlag.requestDecryption() && currentFlag.responseCrypto())) {ServletRequest requestWrapper = new DecryptionRequestUtil(httpServletRequest, password);responseWrapper = new ResponseWrapperUtil(httpServletResponse);chain.doFilter(requestWrapper, responseWrapper);} else if (currentFlag.requestDecryption() && !currentFlag.responseCrypto()) {ServletRequest requestWrapper = new DecryptionRequestUtil(httpServletRequest, password);chain.doFilter(requestWrapper, response);} else if (!currentFlag.requestDecryption() && currentFlag.responseCrypto()) {responseWrapper = new ResponseWrapperUtil(httpServletResponse);chain.doFilter(request, responseWrapper);} else {chain.doFilter(request, response);}if (responseWrapper != null) {byte[] content = responseWrapper.getContent();//获取返回值//判断是否有值if (content.length > 0) {String result = new String(content, "UTF-8");//加密String encryptStr = AesUtil.encrypt(result, password);//把返回值输出到客户端ServletOutputStream out = response.getOutputStream();out.write(encryptStr.getBytes());out.flush();}}}/*** 获取访问目标方法** @param request* @return HandlerExecutionChain* @throws Exception*/private HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {if (this.handlerMappings != null) {for (HandlerMapping hm : this.handlerMappings) {HandlerExecutionChain handler = hm.getHandler(request);if (handler != null) {return handler;}}}return null;}
}

7:定义过滤器的拦截路径

 @Autowiredprivate ApplicationContext applicationContext;/*** 添加加解密过滤器** @return*/@Beanpublic FilterRegistrationBean encryptionDataFilterRegistration() {FilterRegistrationBean<CryptoDecryptionFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new CryptoDecryptionFilter(applicationContext));registration.addUrlPatterns("/*");registration.setName("cryptoDecryptionFilter");registration.setOrder(2);return registration;}

SpringBoot实现数据加密传输相关推荐

  1. Android 和 PHP 之间进行数据加密传输

    Android 和 PHP 之间进行数据加密传输 [代码] [Java]代码 1 mcrypt = new MCrypt(); 2 /* Encrypt */ 3 String encrypted = ...

  2. android网络传输数据加密,Android网络数据加密传输

    在移动应用开发中, 对于数据安全传输要求非常高, 尤其是涉及到用户财产安全的时候,都会对数据进行层层加密来确保数据的安全性 完整性; `在这里演示:我将演示银行在移动应用上的数据加密; 传输的数据格式 ...

  3. 安全扫描:敏感数据加密传输和保存(国密)

    记难受的老项目进行安全扫描的坑:敏感数据加密传输和保存 首先我们先创建这么一个JAVA工具类,用里面的main方法来得到SM2加密时需要用到的公钥和私钥,需要注意的是,执行一次就拿到这两个值来放到另一 ...

  4. springboot整合gprc 传输对象

    2019独角兽企业重金招聘Python工程师标准>>> 一,grpc简介: GRPC是google开源的一个高性能.跨语言的RPC框架,基于HTTP2协议,基于protobuf 3. ...

  5. Android数据加密传输

    客户端在和平台端进行数据的通讯时,有时需要对传输的数据进行加密,下面介绍一些在开发中常用的加解密方法. 一.对称加密 1.对称加密(又称为私人秘钥加密/共享秘钥加密):加密与解密使用同一秘钥,也称为单 ...

  6. 前后端数据加密传输 RSA非对称加密

    任务需求:要求登陆时将密码加密之后再进行传输到后端. 经过半天查询摸索折腾,于是有了如下成果: 加密方式:RSA非对称加密. 实现方式:公钥加密,私钥解密. 研究进度:javascript与java端 ...

  7. DearMob iPhone Manager for Mac(iPhone手机数据加密传输软件)

    DearMob iPhone Manager 是Mac平台上一款功能强大的iPhone数据传输工具,无需iTunes即可完成数据传输.DearMob iPhone Manager Mac版能够为您进行 ...

  8. 微信小程序利用CryptoJS实现DES-ECB数据加密传输

    Step1:添加CryptoJS加密脚本 utils/cryptojs.js var CryptoJS = CryptoJS || function (u, l) {var d = {},n = d. ...

  9. Springboot项目修改文件传输(minio)限制大小

    Springboot项目修改文件传输(minio)限制大小 nginx 配置文件 springboot 项目配置文件 公司文件管理服务使用的 minio,很方便,也很快捷. 有天新来小同事说,mini ...

最新文章

  1. [NOIP2002] 提高组 洛谷P1031 均分纸牌
  2. python getattr_python __getattr__
  3. ui设计现状与意义_想转行UI设计?你必须要了解以下内容
  4. UVA - 12096:The SetStack Computer
  5. python2x 安装 psutil
  6. leetcode 148. 排序链表(归并排序)
  7. @excel注解_Excel导入导出Java解决方案推荐
  8. Java中使用MongoTemplate写聚合函数样例
  9. 上传图片并实现本地预览(1)
  10. 店宝宝电脑版_母婴店主干货分享:母婴店利润究竟有多大?
  11. 个人漂浮装置UL安全标准 - 第 5 部分:浮力辅助设备(50 级) - 安全要求 UL 12402-5介绍
  12. 数据挖掘近年来的研究方向、方法总结
  13. 五类/超五类网线与六类/超六类网线的区别及应用
  14. javplayer 使用教程_PS教程连载第91课:PS核心功能:剪贴蒙版讲解
  15. Informatica使用工作流程及案例1
  16. 0ctf writeup
  17. Taq DNA聚合酶的种类与应用现状
  18. Linux 自定义service,并重定向输出到日志文件
  19. 寒假每日一题 2 : 干草堆 java
  20. VUE纯前端导出excel表格功能《转载》

热门文章

  1. 华为荣耀七刷机后显示无服务器,手机刷机成砖怎么办?华为荣耀7刷机四个须知...
  2. arcsoft人脸识别sdk使用方法(android版本)
  3. c语言获取电脑时间转换成字符串,C语言:获取当前时间,并转为字符串
  4. 什么样的云服务器更受中小型企业的青睐?
  5. 后台网站排版设计与分析
  6. 记一次乐视随身看T50固件telnet的root密码寻找流程
  7. 新东方2021Q3净收入与盈利增长超预期 老牌教育巨头焕发生机?
  8. 计算机毕业设计之java+ssm智慧仓库进销存系统
  9. 服务器临时文件删除bat,删除临时文件的bat文件
  10. android汉字显示问号,易安卓e4a输入中文变成问号解决方法