接口数据脱敏实现方案

SpringBoot接口返回数据脱敏(Mybatis、Jackson) J数据脱敏有以下几种做法: 1、通过自定义Jackson注解,实现在属性序列化过程中处理数据 2、通过Mybatis查询数据时处理 3、其他方式 Jackson是Spring默认的序列化框架,以下将通过自定义Jackson注解,实现在序列化过程中对属性值进行处理。 对于数据库数据的加密解密将采用Mybatis的TypeHandler处理,在我们为数据库提供数据后,会根据我们的需求,对部分数据进行加密。在读取后数据最终到我们手上前,会对读取到数据进行解密。 阅读详情

背景

敏感信息如手机号、身份证、邮箱等信息需要脱敏后展示给前台,如果需要查看,则需要申请权限,查询时需要记录操作日志。

方案

通过JsonSerializer和注解,在json序列化的时候做脱敏操作

此处使用redis存储了加密后的key和明文,如果不需要反查和记录操作日志可以去掉相关代码

流程

代码

脱敏工具类

package com.sky.ddtcode.desensitization;


import cn.hutool.core.util.StrUtil;

/**
 * 脱敏工具类
 */
public class DesensitizedUtil
{
    /**
     * 密码的全部字符都用*代替,比如:******
     *
     * @param password 密码
     * @return 脱敏后的密码
     */
    public static String password(String password)
    {
        if (StrUtil.isBlank(password))
        {
            return StrUtil.EMPTY;
        }
        return StrUtil.repeat('*', password.length());
    }

    /**
     * 车牌中间用*代替,如果是错误的车牌,不处理
     *
     * @param carLicense 完整的车牌号
     * @return 脱敏后的车牌
     */
    public static String carLicense(String carLicense)
    {
        if (StrUtil.isBlank(carLicense))
        {
            return StrUtil.EMPTY;
        }
        // 普通车牌
        if (carLicense.length() == 7)
        {
            carLicense = StrUtil.hide(carLicense, 3, 6);
        }
        else if (carLicense.length() == 8)
        {
            // 新能源车牌
            carLicense = StrUtil.hide(carLicense, 3, 7);
        }
        return carLicense;
    }
}

脱敏策略枚举类

package com.sky.ddtcode.desensitization;

import java.util.function.Function;

/**
 * 脱敏策略,枚举类,针对不同的数据定制特定的策略
 */
public enum SensitiveStrategy
{
    /**
     * 姓名,第2位星号替换
     */
    USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),

    /**
     * 密码,全部字符都用*代替
     */
    PASSWORD(DesensitizedUtil::password),

    /**
     * 身份证,中间10位星号替换
     */
    ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")),

    /**
     * 手机号,中间4位星号替换
     */
    PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),

    /**
     * 电子邮箱,仅显示第一个字母和@后面的地址显示,其他星号替换
     */
    EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")),

    /**
     * 银行卡号,保留最后4位,其他星号替换
     */
    BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")),

    /**
     * 车牌号码,包含普通车辆、新能源车辆
     */
    CAR_LICENSE(DesensitizedUtil::carLicense);

    private final Function<String, String> desensitizer;

    SensitiveStrategy(Function<String, String> desensitizer)
    {
        this.desensitizer = desensitizer;
    }

    public Function<String, String> desensitizer()
    {
        return desensitizer;
    }
}

脱敏注解

package com.sky.ddtcode.desensitization;

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
    //脱敏策略
    SensitiveStrategy strategy();
}

序列化注解自定义实现

此处的加密数据明文存储在redis里面,查询的时候根据rediskey获取数据,并记录操作日志。

此处是为了统一所以采用此种方式,也可以针对单个信息直接接口查询记录操作日志,但是接口会比较多

package com.sky.ddtcode.desensitization;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.Objects;
import java.util.UUID;

/**
 * 序列化注解自定义实现
 * JsonSerializer<String>:指定String 类型,serialize()方法用于将修改后的数据载入
 */
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {

    @Autowired
    RedisService redisService;
    private SensitiveStrategy strategy;

    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        String newValue = strategy.desensitizer().apply(value);
        String guid=UUID.randomUUID().toString();
        String sensitiveValue=newValue+"_"+guid;
        redisService.save(guid,value);
        gen.writeString(sensitiveValue);
        //如果不需要反查明文信息,则可以去掉redisService直接使用下面的代码
        //gen.writeString(strategy.desensitizer().apply(value));
    }

    /**
     * 获取属性上的注解属性
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        Sensitive annotation = property.getAnnotation(Sensitive.class);
        if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
            this.strategy = annotation.strategy();
            return this;
        }
        return prov.findValueSerializer(property.getType(), property);
    }
}

测试实体类

@Data
public class Person {
    /**
     * 真实姓名
     */
    @Sensitive(strategy = SensitiveStrategy.USERNAME)
    private String realName;
    /**
     * 电话号码
     */
    @Sensitive(strategy = SensitiveStrategy.PHONE)
    private String phoneNumber;
    /**
     * 身份证号码
     */
    @Sensitive(strategy = SensitiveStrategy.ID_CARD)
    private String idCard;
}

测试类 

package com.sky.ddtcode.controller;

import com.sky.ddtcode.desensitization.Person;
import com.sky.ddtcode.desensitization.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sensitive")
public class SensitiveController {
    @Autowired
    RedisService redisService;
    @GetMapping("/test")
    public Person test(){
        Person user = new Person();
        user.setRealName("skywhite");
        user.setPhoneNumber("1888888888");
        user.setIdCard("411101199901013344");
        return user;
    }
    //如果不需要反查明文则可以不要这个接口和redisService服务
    @GetMapping("/realValue")
    public String realValue(String guid){
       String value= redisService.getValue(guid);
       //todo  记录操作日志,操作人信息,数据类型信息之类的
        return value;
    }
}

测试

数据加密

明文查询

大厂也在用的6种数据脱敏方案,总结到位 一、MyBatis的框架设计 注:上图很大程度上参考了iteye 上的chenjc_it 所写的博文[原理分析之二:框架整体设计] 中的MyBatis架构体图,chenjc_it总结的非常好,赞一个! 1.接口层—和数据库交互的方式 MyBatis和数据库的交互有两种方式: a.使用传统的MyBatis提供的API; b. 使用Mapper接口 1.1.使用传统的MyBatis提供的API 这是传统的传递Statement Id 和查询参数给SqlSession对象,使用SqlSess 阅读详情

相关推荐

Java数据脱敏实战:基于注解与Jackson序列化的优雅实现方案

数据脱敏是数据安全领域的一项基础技术,其核心原理是在确保数据可用性的前提下,对敏感信息进行变形或遮蔽处理,以保护个人隐私和商业机密。这项技术的核心价值在于平衡数据使用与安全合规,广泛应用于日志输出、接口返回、数据共享与测试环境构建等场景。在Java开发实践中,通过策略模式封装脱敏算法,并结合自定义注解与Jackson序列化器,可以构建出低侵入、高可维护的脱敏框架。本文聚焦于如何利用Spring AOP与自定义JsonSerializer,实现声明式的字段级脱敏,有效解决硬编码与代码重复问题,为处理用户手机号

weixin_30315435的博客 791

接口返回数据字段脱敏处理方案

第四种方案, 增加aop拦截器,在拦截器中的后置处理器中,对返回的参数属性进行解析,带有自定义注解的参数进行拦截,这里兼容了层级复杂多类型的数据结构,不过递归时可能存在内存溢出风险,只要把对象类型的判断处理好就能避免内存泄漏情况。1.新建一个Java类,实现ObjectSerializer接口,重写write 方法,serializer 是序列化对象,object 是属性值,这里我们只需要关注这两个属性,格式化object 内容再写入serializer中就可以了。2.fastjson序列化方式实现脱敏。

qq_38637728的博客 2552

大红球预警版-精选+自定义板块监控

这是一款简单易用的股票大单资金监控插件,兼容通达信软件,可嵌入分时图或定制版面。它以红绿圆球直观显示主力买卖情况(红球为买,绿球为卖),支持300万以上大单语音播报。插件提供实时资金流向分析、多股同时监控、自定义预警条件等功能,无需L2账号。用户可自由切换图形/列表模式,监控特定板块,并配合幻影软件实现自动交易。虽然上涨股通常红球占优,但需结合其他指标综合判断。该插件完全免费,包含详细视频教程,适合新手使用。

guleba的博客 1791

接口数据如何脱敏

接口数据如何脱敏。

weixin_51681634的博客 856

【PowerHarmony】电鸿蒙学习记录-准备工作

将获取的“PowerHarmony_PHM_SDK_V1.0.1.0.tar.gz”进行解压。将获取的“code_1.91.1-1720564633_amd64.deb”进行解压。打开后可见所有文件夹,即可进行编辑开发,VSCode也可打开终端进行编译等调试。选择主控类型,我是用的是gd32f470,我选gd32f4xx。Open Folder路径选中SDK解压后根目录即可。选择对应系统类型,我的是小型的,我选mini。选好后即完成工程创建。

Allenzhu的博客 2724

Python异步协程爬虫优化:解决aiohttp中ServerDisconnectedError的高效策略

本文深入探讨了在Python异步协程爬虫中使用aiohttp时,如何高效解决常见的ServerDisconnectedError问题。核心策略包括全局复用ClientSession、精细配置TCPConnector连接池、实施请求重试与速率限制,从而构建稳定、高效的异步爬虫架构,有效避免服务器断开连接错误。

pz890123的博客 857

SpringBoot实战:轻松实现接口数据脱敏

本文深入探讨了在SpringBoot应用程序中实施数据脱敏策略的关键性,并提出了一种创新的解决方案,即通过集成自定义注解与Hutool脱敏工具类来高效地实现数据脱敏。此方案旨在精准地对敏感信息进行脱敏处理,确保用户隐私得到妥善保护,同时维护数据的安全性。我们期待这一方案能为开发者们提供有价值的参考,共同提升数据保护水平。😊。

Z99263的博客 1541

解决Keil uVision许可证管理中Unknown Product错误

嵌入式开发中,IDE工具的许可证管理是确保开发环境正常运行的关键环节。Keil uVision作为ARM架构的主流开发工具,其许可证系统采用加密验证机制,通过产品版本识别实现授权控制。当出现Unknown Product错误时,通常源于版本兼容性问题或区域发行版差异,这直接影响开发工具链的可用性。特别是在维护历史项目或使用中国特供版时,开发者常会遇到此类问题。通过分析许可证类型、调整安装配置或建立虚拟化开发环境等工程实践方案,可以有效解决这类授权验证故障,保障嵌入式项目的持续集成与交付效率。

weixin_33743248的博客 363

【SpringBoot】三种常见的数据脱敏方案

大家可以根据自己的想法添加其它的脱敏规则(我只想脱敏一部分数据,并指明从哪开始,从哪结束)。要做成可配置多策略的脱敏操作,要不然一个个接口进行脱敏操作,重复的工作量太多。定义数据脱敏注解和数据脱敏逻辑的接口, 在返回类上,对需要进行脱敏的属性加上,并指定对应的脱敏策略操作。4、自定义 AnnotationIntrospector,适配我们自定义注解返回相应的Serializer。由于 Java 8 中新增了许多函数式接口,所以,这里就不需要我们自定义接口了,可以直接使用函数式接口。方案三、自定义注解实现。.

sco5282的博客 1万+

正弦波产生电路_文氏桥振荡

本文以文氏桥振荡为基础产生正弦波,介绍了原理、计算、应用时需要注意的一些点,并给出了实测可用的电路模板

白鹤忘机的博客 3万+

微信小程序:errno: 600001, errMsg: “uploadFile:fail errcode:-101 cronet_error_code:-10001 error_msg:net::E

微信小程序报错uploadFile:fail errcode:-101 cronet_error_code:-10001 error_msg:net::ERR_CONNECTION_RESET, custum ip is invalid, didn't find user's ip,wx.uploadFile errno: 600001 errcode:-101 ?微信小程序wx.uploadFile错误,wx.uploadFile 在真机上报下面的错误,调试工具里没有问题,其它接口在真机/调试工具都正常,

✅ 精选推荐文章 4257

Spring Boot + Jackson 实现优雅的接口数据脱敏方案

Spring Boot + Jackson 实现优雅的接口数据脱敏方案

s20050830的博客 383

AIO-1126-JD4(RV1126)蓝牙通讯(BLE)

AIO-1126-JD4采用了正基科技推出的一款集成WiFi、蓝牙功能的模组AP6236,支持高速(HS)功能的蓝牙 4.0,集成了 1.5 类功率放大器(PA),并支持低功耗蓝牙(BLE)。提到正基就不得不提下博通。博通和正基是芯片技术与模块制造方面的合作关系,正基科技是中国台湾的公司,在无线通信模块领域有一定的市场份额,博通则是全球领先的有线和无线通信半导体公司。正基把包含博通关键IP的核心芯片和自家的射频部分等封装在一起,即SIP(System In Package)。

w1820020635的博客 1121

优雅的数据脱敏

*** 自定义jackson注解,标注在属性上*///脱敏策略使用注解@Sensitive@Data/*** 真实姓名*//*** 地址*//*** 电话号码*//*** 身份证号码*/数据脱敏有很多种实现方式,关键是哪种更加适合,哪种更加优雅.....

yunyunxiaosheng的博客 517

BAQ压缩原理

BAQ——Block Adaptive Quantization,块自适应量化,一种数据压缩算法。

2867

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

项目实战--数据脱敏方案

实际的业务开发过程中,对隐私数据进行脱敏处理设计方案

qq_40623672的博客 829

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

java 日志的数据脱敏

思路 1。在 model层进行处理,直接重写get方法,在写一个getPlain 获取明文方法。(缺点:数据库写入和json序列化传递时使用的都是密文)   2.利用 日志组件过滤 特定的key,去进行脱敏(缺点:对所有的日志输出全部要正则匹配,非常耗时。) 由1,2的利弊,肯定会选择1,然后考虑一种实现(在model层定义方法,获取它的一个复制类,复制类里面的信息都是脱敏的,日志输...

dianliangpi8063的博客 204

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

系统可控实现方案

通过约定一个加密算法,客户端在发起请求时将所有的非空参数按程序拼接在一起,形成一个sign,并将其放在请求头中传递给后端服务,后端服务端使用相同的算法生成sign,并将其与传入的sign进行比较,以判断是否被篡改。加解密是保护数据安全和防止数据泄露的重要手段。总结: 通过以上方案和技术的应用,可以有效实现系统的可控性,保护用户数据的安全和隐私,防止接口数据的篡改、暴力请求以及数据的泄密。系统可控实现方案是指通过一系列的技术和策略,确保系统在运行过程中受到合理的保护,防止数据被篡改、泄密以及暴力请求的攻击。

凯哥Java的博客 1267

一个注解搞定接口返回数据脱敏

下午惬意时光,突然产品小姐姐走到我面前,打断我短暂的摸鱼time,企图与我进行深入交流,还好我早有防备没有闪,打开瑞star的点单页面,暗示没有一杯coffee解决不了的需求,需求是某些接口返回的信息,涉及到敏感数据的必须进行脱敏操作,我思考一反,表示某问题,马上安排思路要做成可配置多策略的脱敏操作,要不然一个个接口进行脱敏操作,重复的工作量太多,很显然违背了“多写一行算我输”的程序员规范,思来想...

Java知音 384

springbopot使用ResponseBodyAdvice数据脱敏

先写User、Order、Result三个实体类(Result是接口统一返回格式):@Data// 需要脱敏的字段// 需要脱敏的字段@Data// 需要脱敏的字段// 嵌套对象,里面的phone需要脱敏// Result.java:接口统一返回格式@Data// 状态码:200=成功,500=失败// 提示信息// 响应数据// 成功返回// 失败返回。

xlf372332909的博客 1355

SpringBoot 接口数据如何实现优雅的脱敏?

实现方案:自定义注解 + Jackson序列化器。

m0_46617601的博客 310

一个注解搞定接口数据脱敏,太强了!

一个注解搞定接口数据脱敏,太强了!

weixin_45623983的博客 299

Apache ShardingSphere数据脱敏全解决方案详解(下)

ApacheShardingSphere数据脱敏全解决方案详解(下)作者介绍潘娟,京东数科高级DBA,主要负责京东数科数据库中间件开发、数据库运维自动化平台开发、生产数据...

ShardingSphere官微 3494

基于AOP的Controller接口脱敏方式

目录前言常见方案方案一方案二方案三实现方式两个注解类切面类脱敏序列化类接口类接口调用踩过的坑 前言 我们的后台系统收到了数据脱敏的需求, 要求在一些关联页面的手机号, 收货地址等重要信息需要进行脱敏显示. 所以才有了这个脱敏方案 常见方案 方案一 在关键的DTO 和VO上增加注解, 然后这些对象通过接口返回调用者的时候, 会屏蔽掉注释字段的值. 优点: 只要增加了注释, 所有的返回这个对象的接口都会屏蔽, 不用每个接口单独写代码 缺点: 无法针对特定的接口精细化控制 返回的前端的DTO对象是其

之城的专栏 1952

Java 实现数据脱敏

Java 实现数据脱敏 Java注解实现数据脱敏-与主业务解耦且权限管控关联【小兀军】https://mp.weixin.qq.com/s/RujXqk0MWhmtQKpf_zaTnQ Springboot日志、配置文件、接口数据如何脱敏?老鸟们都是这样玩的【架构师社区】https://mp.weixin.qq.com/s/uKlit0Cu8ZhqM_1I1_N-9Q ...

路边烧卖 1380
上一篇: spring全局异常处理类ExceptionHandler获取request入参
下一篇: 12个乒乓球,有一个次品,不知轻重,用一台无砝码天平称三次,找出次品,告知轻重?
bxp1321
博客等级 码龄17年 146粉丝 86原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值