文章目录
- 引言
- 一、接口数据脱敏概述
-
- 1.1 接口数据脱敏的定义
- 1.2 接口数据脱敏的重要性
- 1.3 接口数据脱敏的实现方式
- 二、开发环境
- 三、实现接口返回数据脱敏
-
- 3.1 添加依赖
- 3.2 创建自定义注解
- 3.3 定义脱敏枚举类
- 3.4 创建自定义序列化类
- 四、测试
-
- 4.1 编写测试代码
- 4.2 测试
- 五、总结
引言
在当今的信息化时代,数据安全尤为重要。接口返回数据脱敏是一种重要的数据保护手段,可以防止敏感信息通过接口返回给客户端,降低数据泄露的风险。本文旨在探讨如何在SpringBoot应用程序中实现接口返回数据脱敏。我们将介绍一种基于自定义注解结合Hutool脱敏工具类的方案,以实现SpringBoot中的接口返回数据脱敏。
一、接口数据脱敏概述
1.1 接口数据脱敏的定义
接口数据脱敏是指在Web应用程序的API接口返回数据时,对包含敏感信息的字段进行处理,使其部分或全部信息被隐藏或替换,以防止敏感信息的泄露。这个过程通常不会改变数据的原始格式,而是通过特定的算法或规则,将敏感部分替换为特定字符(如星号*)或者保留部分信息。
1.2 接口数据脱敏的重要性
数据脱敏的重要性主要体现在以下几个方面:
- 保护用户隐私: 对于姓名、身份证号、手机号等个人敏感信息进行脱敏,可以有效保护用户隐私,防止信息被滥用。
- 遵守法律法规: 许多国家和地区都制定了严格的数据保护法规,如欧盟的GDPR和中国的《个人信息保护法》。实施数据脱敏有助于企业合规经营。
- 降低安全风险: 通过脱敏处理,即使数据不慎泄露,也能最大限度地减少敏感信息被盗用的风险。
- 支持数据共享: 在保护隐私的同时,脱敏数据仍然保留了一定的分析价值,有利于数据的安全共享和利用。
1.3 接口数据脱敏的实现方式
-
手动脱敏:在业务逻辑层直接对敏感数据进行处理。这种方式灵活但容易遗漏,且代码重复率高。
-
AOP(面向切面编程):通过切面拦截返回数据,统一处理敏感字段。这种方式可以集中管理脱敏逻辑,但可能影响性能。
-
自定义序列化器:利用JSON序列化框架(如Jackson)的自定义序列化器来处理敏感字段。这种方式性能较好,且与业务逻辑解耦。
-
注解+反射:通过自定义注解标记需要脱敏的字段,然后利用反射机制在运行时进行脱敏处理。这种方式使用简单,易于维护。
本文将重点介绍如何结合自定义注解和Hutool工具类来实现接口数据脱敏。
二、开发环境
- JDK版本:JDK 17
- Spring Boot版本:Spring Boot 3.2.2
- 构建工具:Maven
三、实现接口返回数据脱敏
3.1 添加依赖
首先在 pom.xml
文件中添加必要的依赖:
<!-- Hutool工具包 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.25</version>
</dependency>
<!-- Jackson依赖 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.2</version>
</dependency>
3.2 创建自定义注解
接下来,我们创建一个自定义注解 @Desensitize
:
/**
* 用于标记字段需要进行脱敏处理的注解
*
* @author shijun
* @date 2024/07/09
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizeSerializer.class)
public @interface Desensitize {
/**
* 脱敏类型
*/
DesensitizeType type() default DesensitizeType.DEFAULT;
/**
* 脱敏起始位置
*/
int startInclude() default 0;
/**
* 脱敏结束位置
*/
int endExclude() default 0;
}
3.3 定义脱敏枚举类
然后,定义枚举类 DesensitizeType
来定义字段的脱敏类型:
/**
* 脱敏类型枚举类
*/
public enum DesensitizeType {
/**
* 默认脱敏
*/
DEFAULT,
/**
* 自定义脱敏
*/
CUSTOM_RULE,
/**
* 手机号脱敏
*/
PHONE,
/**
* 电子邮件脱敏
*/
EMAIL,
/**
* 身份证号脱敏
*/
ID_CARD,
/**
* 银行卡号脱敏
*/
BANK_CARD,
/**
* 地址脱敏
*/
ADDRESS,
/**
* 中文姓名脱敏
*/
CHINESE_NAME,
/**
* 密码脱敏
*/
PASSWORD,
}
3.4 创建自定义序列化类
Hutool支持的脱敏数据类型包括:
- 用户id
- 中文姓名
- 身份证号
- 座机号
- 手机号
- 地址
- 电子邮件
- 密码
- 中国大陆车牌,包含普通车辆、新能源车辆
- 银行卡
整体来说,所谓脱敏就是隐藏掉信息中的一部分关键信息,用
*
代替。大家可以自己看一看DesensitizedUtil
类中方法,其实就是replace
方法和hide
方法的使用,想要自定义规则进行隐藏可以仿照进行实现。
/**
* 脱敏序列化器,用于在序列化字符串时根据不同的脱敏类型进行数据脱敏。
*
* @author shijun
* @date 2024/07/08
*/
public class DesensitizeSerializer extends JsonSerializer<String> implements ContextualSerializer {
/**
* 脱敏类型,默认为DEFAULT
*/
private DesensitizeType type;
/**
* 脱敏起始位置
*/
private int startInclude;
/**
* 脱敏结束位置
*/
private int endExclude;
public DesensitizeSerializer() {
this.type = DesensitizeType.DEFAULT;
}
public DesensitizeSerializer(DesensitizeType type) {
this.type = type;
}
/**
* 序列化字符串时调用,根据脱敏类型对字符串进行相应的脱敏处理。
*
* @param value 待序列化的字符串
* @param gen JSON生成器,用于写入处理后的字符串
* @param serializers 序列化器提供者,用于获取其他序列化器
* @throws IOException 如果序列化过程中发生I/O错误
*/
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
switch (type) {
case CUSTOM_RULE:
// 这里是对字符串的startInclude到endExclude字段进行隐藏处理,如果想要实现两端保留,可以考虑使用StrUtil的replace方法
gen.writeString(StrUtil.hide(value, startInclude, endExclude));
break;
case PHONE:
gen.writeString(DesensitizedUtil.mobilePhone(value));
break;
case EMAIL:
gen.writeString(DesensitizedUtil.email(value));
break;
case ID_CARD:
gen.writeString(DesensitizedUtil.idCardNum(value, 1, 2));
break;
case BANK_CARD:
gen.writeString(DesensitizedUtil.bankCard(value));
break;
case ADDRESS:
gen.writeString(DesensitizedUtil.address(value, 8));
break;
case CHINESE_NAME:
gen.writeString(DesensitizedUtil.chineseName(value));
break;
case PASSWORD:
gen.writeString(DesensitizedUtil.password(value));
break;
default:
gen.writeString(value);
break;
}
}
/**
* 根据上下文信息创建自定义的序列化器,用于处理带有@Desensitize注解的属性。
*
* @param prov 序列化器提供者,用于获取其他序列化器
* @param property 当前属性的信息,用于获取注解和属性类型
* @return 自定义的序列化器实例
*/
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
if (property != null) {
Desensitize annotation = property.getAnnotation(Desensitize.class);
if (annotation != null) {
this.type = annotation.type();
if (annotation.type() == DesensitizeType.CUSTOM_RULE) {
this.startInclude = annotation.startInclude();
this.endExclude = annotation.endExclude();
}
}
}
return this;
}
}
代码分析:
serialize
方法在序列化字符串时被调用,根据脱敏类型对字符串进行相应的脱敏处理。根据不同的脱敏类型,使用不同的处理方法对字符串进行脱敏,并将处理后的字符串写入JSON生成器中。createContextual
方法根据上下文信息创建自定义的序列化器,用于处理带有@Desensitize
注解的属性。它通过获取注解中的脱敏类型和自定义规则的起始位置和结束位置,对实例进行相应的设置,并返回自定义的序列化器实例。这个序列化器的主要用途是在 JSON 序列化过程中自动对标记了
@Desensitize
注解的字段进行脱敏处理。
四、测试
4.1 编写测试代码
- 编写实体类
@Data
public class UserDTO {
/**
* 用户姓名
*/
@Desensitize(type = DesensitizeType.CHINESE_NAME)
private String name;
/**
* 用户手机号
*/
@Desensitize(type = DesensitizeType.PHONE)
private String phoneNumber;
/**
* 用户电子邮件地址
*/
@Desensitize(type = DesensitizeType.EMAIL)
private String email;
/**
* 用户密码
*/
@Desensitize(type = DesensitizeType.PASSWORD)
private String password;
/**
* 用户身份证号码
*/
@Desensitize(type = DesensitizeType.ID_CARD)
private String idCard;
/**
* 用户银行卡号
*/
@Desensitize(type = DesensitizeType.BANK_CARD)
private String bankCard;
/**
* 用户地址
*/
@Desensitize(type = DesensitizeType.ADDRESS)
private String address;
/**
* 游戏名称
*/
@Desensitize(type = DesensitizeType.CUSTOM_RULE, startInclude = 2, endExclude = 6)
private String gameName;
}
- 编写测试接口
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping("/desensitize")
public UserDTO getUser() {
UserDTO userDTO = new UserDTO();
userDTO.setName("孙大圣");
userDTO.setEmail("shijun@163.com");
userDTO.setPhoneNumber("12345678901");
userDTO.setPassword("123456");
userDTO.setAddress("辽宁省盘锦市兴隆台区红村乡441号");
userDTO.setIdCard("447465200912089605");
userDTO.setBankCard("6217000000000000000");
userDTO.setGameName("超级无敌大铁锤");
return userDTO;
}
}
4.2 测试
题外话
黑客&网络安全如何学习
今天只要你给我的文章点赞,我私藏的网安学习资料一样免费共享给你们,来看看有哪些东西。
1.学习路线图
攻击和防守要学的东西也不少,具体要学的东西我都写在了上面的路线图,如果你能学完它们,你去就业和接私活完全没有问题。
2.视频教程
网上虽然也有很多的学习资源,但基本上都残缺不全的,这是我自己录的网安视频教程,上面路线图的每一个知识点,我都有配套的视频讲解。
内容涵盖了网络安全法学习、网络安全运营等保测评、渗透测试基础、漏洞详解、计算机基础知识等,都是网络安全入门必知必会的学习内容。
(都打包成一块的了,不能一一展开,总共300多集)
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
3.技术文档和电子书
技术文档也是我自己整理的,包括我参加大型网安行动、CTF和挖SRC漏洞的经验和技术要点,电子书也有200多本,由于内容的敏感性,我就不一一展示了。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
4.工具包、面试题和源码
“工欲善其事必先利其器”我为大家总结出了最受欢迎的几十款款黑客工具。涉及范围主要集中在 信息收集、Android黑客工具、自动化工具、网络钓鱼等,感兴趣的同学不容错过。
还有我视频里讲的案例源码和对应的工具包,需要的话也可以拿走。
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
最后就是我这几年整理的网安方面的面试题,如果你是要找网安方面的工作,它们绝对能帮你大忙。
这些题目都是大家在面试深信服、奇安信、腾讯或者其它大厂面试时经常遇到的,如果大家有好的题目或者好的见解欢迎分享。
参考解析:深信服官网、奇安信官网、Freebuf、csdn等
内容特点:条理清晰,含图像化表示更加易懂。
内容概要:包括 内网、操作系统、协议、渗透测试、安服、漏洞、注入、XSS、CSRF、SSRF、文件上传、文件下载、文件包含、XXE、逻辑漏洞、工具、SQLmap、NMAP、BP、MSF…
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
🐵这些东西我都可以免费分享给大家,需要的可以点这里自取👉:网安入门到进阶资源
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文转自 https://blog.youkuaiyun.com/weixin_73588491/article/details/140304117,如有侵权,请联系删除。