请求参数和应答数据统一加解密

2023-05-16

一,针对请求参数和应答数据都是json格式时,可以通过,下面的方式,进行统一的的加解密。

1. 设置配置文件。


 @Bean
    public MappingJackson2HttpMessageConverter customJackson2HttpMessageConverter() {
        MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    
        /** SimpleModule 入参xss处理、返回BigDecimal类型处理 */
        SimpleModule module = new SimpleModule("XssStringJsonSerializer");
        module.addDeserializer(String.class,new JsonHtmlXssDeserializer(String.class));
        objectMapper.registerModule(module);

        List<MediaType> mediaTypeList = new ArrayList<>();
        mediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
        jsonConverter.setSupportedMediaTypes(mediaTypeList);
        jsonConverter.setObjectMapper(objectMapper);
        return jsonConverter;
    }  

2.编写JsonHtmlXssDeserializer 类,对请求参数进行解密处理。

public class JsonHtmlXssDeserializer extends JsonDeserializer<String> {

    private static final String SM4Prefix = "Z@!@$B";

    public JsonHtmlXssDeserializer(Class<String> string) {
        super();
    }

    @Override
    public Class<String> handledType() {
        return String.class;
    }

    @Override
    public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        String value = jsonParser.getValueAsString();
        if (value != null) {
            if(value.startsWith(SM4Prefix)){
                value = value.substring(6);
                try {
                    value = SM4.sm4Decrypt(value);
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new IOException("json 解密失败");
                }
            }
            return value;
        }
        return value;
    }
}
 

编写完毕后,只要字符串的前缀为Z@!@$B时,会执行 SM4 的解密程序。

3.编写应当数据统一加密的方法

自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Documented
@JacksonAnnotationsInside
@Target(ElementType.FIELD)
@JsonSerialize(using = EncryptDataSerializer.class)
public @interface EncryptData {
    

    /**
     * 加密策略
     */
    Strategy strategy() default Strategy.SM4;

    Methods methods() default Methods.ENCRYPT;

    
    enum Strategy {
        /**
         * SM4
         */
        SM4,
        /**
         * AES
         */
        AES,
        /**
         * 从右边开始
         */
        RIGHT
    }

    enum Methods {
        /**
         * 对字段加,解密
         */
         ALL,
        /**
         * 仅加密
         */
        ENCRYPT,
        /**
         * 仅解密
         */
        DECRYPT
    }
}
 

定义aop,真对注解进行处理:

@Component
@Slf4j
@Aspect
public class DecryptAspect {

    final static Logger logger = LoggerFactory.getLogger(DecryptAspect.class);

    @Before(value = "execution(public * com.ruoyi.project.system.controller.*Controller.*(..))")
    public void before(JoinPoint joinPoint) {

        Object[] obj = joinPoint.getArgs();
        if (null != obj) {
            int len = obj.length;
            for (int i = 0; i < len; i++) {
                Object item = obj[i];
                if (item == null) {
                    return;
                }
                Field[] fields = item.getClass().getDeclaredFields();
                // 遍历所有字段
                for (Field field : fields) {
                    // 若该字段被SecurityParameter注解,则进行解密/加密
                    Class<?> fieldType = field.getType();
                    if (fieldType == String.class) {
                        EncryptData encryptData =AnnotationUtils.findAnnotation(field, EncryptData.class);
                        if (null != encryptData) {
                            // 设置private类型允许访问
                            try {
                                field.setAccessible(Boolean.TRUE);
                                handleField(item, field, encryptData);
                                field.setAccessible(Boolean.FALSE);
                            }catch (Exception ex){
                                logger.error("解压失败!",ex.fillInStackTrace());
                            }
                        }
                    }


                }
            }

        }
    }

    private  void handleField(Object item, Field field,EncryptData encryptData) throws Exception {
        if (null == item) {
            return;
        }
        if(field.get(item) == null){
            return;
        }
        String str = field.get(item).toString();
        final EncryptData.Methods methods = encryptData.methods();
        switch (encryptData.strategy()){
            case SM4:
                try {
                    if(methods == EncryptData.Methods.ALL ||
                            methods == EncryptData.Methods.DECRYPT) {
                        field.set(item,SM4.sm4Decrypt(str));
                    }

                }catch (Exception ex){
                    logger.error("sm4加密失败",ex.getCause());
                }

                return;
            case AES:
                return;
            default:
                throw new IllegalArgumentException("Illegal Sensitive Strategy");
        }

    }
}
 

EncryptDataSerializer 重新序列化接口:

public class EncryptDataSerializer extends JsonSerializer<String> implements ContextualSerializer {

    final Logger logger = LoggerFactory.getLogger(EncryptDataSerializer.class);
    private EncryptData encryptData;

    public EncryptDataSerializer(EncryptData encryptData) {

        this.encryptData = encryptData;
    }

    public EncryptDataSerializer() {
    }


    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        if (StringUtils.isBlank(value)) {
            gen.writeString(value);
            return;
        }

        if (encryptData != null) {
            final EncryptData.Strategy strategy = encryptData.strategy();
            final EncryptData.Methods methods = encryptData.methods();
            gen.writeString(getValue(value, strategy,methods));
        } else {
            gen.writeString(value);
        }

    }

    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
        EncryptData annotation = property.getAnnotation(EncryptData.class);

        if (annotation != null) {
            return new EncryptDataSerializer(annotation);
        }
        return this;
    }

    private String getValue(String rawStr, EncryptData.Strategy strategy, EncryptData.Methods methods) {
       String strBack="";
        switch (strategy) {
            case SM4:
                try {
                    if(!StringUtils.isEmpty(rawStr)) {
                        if(methods == EncryptData.Methods.ALL ||
                                methods == EncryptData.Methods.ENCRYPT) {
                            strBack = SM4.sm4Encode(rawStr);
                        }
                    }
                }catch (Exception ex){
                    logger.error("sm4加密失败",ex.getCause());
                }
                return strBack;
            case AES:
                return rawStr;
            default:
                throw new IllegalArgumentException("Illegal Sensitive Strategy");
        }
    }

   
}

只要在定义的实体类上添加,EncryptData 注解,返回的字段就会sm4进行加密(注意:字段类型必须为String)

如: @EncryptData(strategy = EncryptData.Strategy.SM4,methods = EncryptData.Methods.ALL)
    /** 手机号码 */
    @Excel(name = "手机号码")
    private String phonenumber;

应答信息返回:

 phonenumber 字段会进行sm4加密。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

请求参数和应答数据统一加解密 的相关文章

  • 20万到100万年薪的算法工程师有什么区别?

    公元七世纪 xff0c 在车迟国国家气象局组织的一次求雨活动中 xff0c 虎力 鹿力 羊力三位大仙成功地祈下甘霖 xff0c 救黎民于水火中 老国王虽然不明就里 xff0c 却从此尊他们为国师 xff0c 奉道教为圭臬 本世纪 xff0c
  • 关于handler的内存泄漏的总结

    本文并非完全是原创 有网络上边的 也有自己的思考与总结 本文主要有三部分来介绍handler的介绍 第一 熟悉一下handler的流程 1 当Android程序第一次创建的时候 xff0c 在主线程同时会由ActivityThread 创建
  • Android 设置应用的底部导航栏(虚拟按键)背景颜色

    Android手机机型种类繁多 但是虚拟按键也就是底部的导航栏 不外乎两种设计方式 一种是作为虚拟按键设计到屏幕内部 一种是作为系统按键设计到屏幕外面 对于按键在屏幕内部的机型 因为虚拟按键也是屏幕内容的一部分 它也实际占据屏幕一定的高度
  • Adobe XD使用心得及简单使用技巧

    关于Adobe XD Adobe XD xff0c 全称Adobe Experience Design 这是一款集原型 设计和交互于一体的小清新时代风格的设计软件 虽然传言中 xff0c Adobe XD将会是skech的劲敌 然而在win
  • 生产者消费者问题(代码实现)

    生产者 消费者问题 xff08 也被称为有界缓冲器问题 xff09 是一个典型的例子多线程同步的问题 问题描述了两个进程 xff0c 生产者和消费者 xff0c 谁都有一个共同的 xff0c 固定大小的缓冲区作为一个队列 制片人的工作是生成
  • BIO与NIO的方式实现文件拷贝

    面试题 编程实现文件拷贝 xff08 这个题目在笔试的时候经常出现 xff0c 下面的代码给出了两种实现方案 xff09 span class hljs keyword import span java io FileInputStream
  • Linux上jmeter-server启动失败

    贴个广告 楼主的博客已全部搬迁至自己的博客 xff0c 感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏 Jmeter server启动失败 xff1a Cannot start Unable to get local host I
  • zabbix 5.4 添加报警动作

    我们先来看一下zabbix动作事件的整个流程 xff0c 通过下面的流程图希望大家对zabbix的报警功能要有一个整体上的认识 一个完整的报警功能必要条件 xff1a 监控项 xff1a 用于实时采集主机的数据 xff08 CPU xff0
  • Mysql的七种join

    对于SQL的Join xff0c 在学习起来可能是比较乱的 我们知道 xff0c SQL的Join语法有很多inner的 xff0c 有outer的 xff0c 有left的 xff0c 有时候 xff0c 对于Select出来的结果集是什
  • shell脚本实现自动保留最近n次备份记录

    贴个广告 楼主的博客已全部搬迁至自己的博客 xff0c 感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏 项目中出现的问题 某天上午服务器出现卡顿特别严重 xff0c 页面加载速度奇慢 xff0c 并且某些页面刷新出现404的问题
  • Java实现终止线程池中正在运行的定时任务

    贴个广告 楼主的博客已全部搬迁至自己的博客 xff0c 感兴趣的小伙伴请移步haifeiWu与他朋友们的博客专栏 源于开发 最近项目中遇到了一个新的需求 xff0c 就是实现一个可以动态添加定时任务的功能 说到这里 xff0c 有人可能会说
  • TCP 粘包问题浅析及其解决方案

    最近一直在做中间件相关的东西 xff0c 所以接触到的各种协议比较多 xff0c 总的来说有TCP xff0c UDP xff0c HTTP等各种网络传输协议 xff0c 因此楼主想先从协议最基本的TCP粘包问题搞起 xff0c 把计算机网
  • Redis协议规范(译文)

    原文地址 xff1a haifeiWu的博客 博客地址 xff1a www hchstudio cn 欢迎转载 xff0c 转载请注明作者及出处 xff0c 谢谢 xff01 Redis客户端使用名为RESP xff08 Redis序列化协
  • Netty 源码中对 Redis 协议的实现

    原文地址 xff1a haifeiWu的博客 博客地址 xff1a www hchstudio cn 欢迎转载 xff0c 转载请注明作者及出处 xff0c 谢谢 xff01 近期一直在做网络协议相关的工作 xff0c 所以博客也就与之相关
  • 高性能无锁队列 Disruptor 初体验

    原文地址 xff1a haifeiWu和他朋友们的博客 博客地址 xff1a www hchstudio cn 欢迎转载 xff0c 转载请注明作者及出处 xff0c 谢谢 xff01 最近一直在研究队列的一些问题 xff0c 今天楼主要分
  • MYSQL快速导入大量数据 - LOAD DATA INFILE

    问题背景 xff1a 在做性能测试时 xff0c 通常需要根据业务模型在数据库中预置大量数据 我一开始的做法是使用python生成INSERT INTO语句的SQL脚本后 xff0c 再导入对应数据库 使用中会发现速度很慢 xff0c 10
  • Postman使用教程 - 导入请求(Import)

    Postman是一个有着图形化界面的API请求模拟平台 xff0c 在构造请求时最常见的莫过于手动在对应的输入框中填入相应的内容 xff1a 根据被测HTTP请求的Method URL Headers Request Params Body
  • Daily Cost 介绍

    Daily Cost是我为了学习前后端开发的产出成果 从应用名可以看出是一个记账本应用 xff0c 主要参考了鲨鱼记账 xff0c 我从中挑选了一部分核心功能来自己开发实现 1 功能模块 作为一个正经的记账本应用 xff0c 肯定要能满足用
  • zabbix5.4 如何配置报警一次

    如果小伙伴们在认真跟着大叔配置zabbix的话 xff0c 相信你现在已经至少配置好了自己的邮件报警了 可是你可能正在和我一样陷入到一个新的烦恼之中 xff0c 那就是zabbix 邮件轰炸机 xff08 呵呵 xff0c 暂时这么叫吧 x

随机推荐