保护用户隐私:Spring Boot 数据脱敏实战

保护用户隐私:Spring Boot 数据脱敏实战

在开发过程中,我们要防止内部数据、账号等泄漏,如果导致核心数据外漏,这种事的后果可大可小,所以实际开发中需要配置文件内容都加密了,数据安全问题真的不容小觑,敏感数据一定要做脱敏处理。

今日内容介绍,大约花费12分钟

保护用户隐私:Spring Boot 数据脱敏实战
#代码地址
https://github.com/bangbangzhou/springboot-learn/tree/main/spring-boot-jasypt-demo

1. 配置脱敏

在Spring Boot开发中,使用Jasypt(Java Simplified Encryption)对配置进行脱敏相对简单的 jasypt存在两种加密方式:

  • 单密钥对称加密:一个密钥加盐,可以同时用作内容的加密和解密依据;

  • 非对称加密:使用公钥和私钥两个密钥,才可以对内容加密和解密;

以上两种加密方式使用都比较简单,我们以springboot单密钥对称加密方式做示例


1.1. 添加jasypt依赖

在pom.xml中添加jasypt-spring-boot-starter依赖:


<!--配置文件加密-->
<dependency>
    <groupId>com.github.ulisesbocchio</groupId>
    <artifactId>jasypt-spring-boot-starter</artifactId>
    <version>2.1.0</version>
</dependency>

1.2. 配置应用属性

在application.yml文件中配置Jasypt的对称加密密码,并将需要脱敏的value值替换成预先经过加密的内容ENC(daV7F8cFzZBTzwSQ4gVGAw==)

spring:
  application:
    name: backend #指定服务名
  datasource:
    username: root
    password: ENC(daV7F8cFzZBTzwSQ4gVGAw==)
    url: jdbc:mysql://localhost:3306/backend_db?useUnicode=true&characterEncoding=utf8
    driver-class-name: com.mysql.cj.jdbc.Driver
#    password: zbb[daV7F8cFzZBTzwSQ4gVGAw==]
# 秘钥 
jasypt:
  encryptor:
    password: zbbmeta 
#    property:
#      prefix: "zbb["
#      suffix: "]"

注意点:


    1. 加密的内容格式可以随意定义,比如我们需要zbb[daV7F8cFzZBTzwSQ4gVGAw==],只需要配置前后缀即可
jasypt:
  encryptor:
    property:
      prefix: "zbb["
      suffix: "]"

    1. 一般密钥不建议存放在项目中,特别是生产环境,我们可以通过启动环境参数进行配置,或者存放在配置中心
java -jar -Djasypt.encryptor.password=zbbmeta  spring-boot-jasypt-demo-1.0-SNAPSHOT.jar

    1. Jasypt加解密值,可以通过代码内调用API生成
@SpringBootTest
public class JasyptTest {

    @Autowired
    private StringEncryptor stringEncryptor;

    @Test
    public void test1(){
        String encryptStr = stringEncryptor.encrypt("root");
        System.out.println("加密后的内容:" + encryptStr);
    }

    @Test
    public void test2(){


        String decrypt = stringEncryptor.decrypt("23WuA8R+tUK7pIfurUH38Q==");
        System.out.println("解密后的内容:" + decrypt);
    }
保护用户隐私:Spring Boot 数据脱敏实战
保护用户隐私:Spring Boot 数据脱敏实战

2. 敏感字段脱敏

项目中用户的隐私数据,比如手机号、身份证或者一些账号配置等信息,入库时都要进行不落地脱敏,也就是在进入我们系统时就要实时脱敏处理。

比如登录,用户在前端就会对密码进行加密,传入到后台后就需要进行脱敏,以供后端使用使用或者持久化到数据库;当用户查询数据时,我们从数据库查询出数据是正常数据,但是为了防止泄密,我们需要响应到前端前进行加密

思考:我们该如何去实现?AOP实现敏感字段的加密和解密是再好不过

2.1.  创建自定义注解

首先自定义两个注解@SensitiveField、@SensitiveMethod分别用在字段属性和方法上,实现思路很简单,只要方法上应用到@SensitiveMethod注解,则检查入参对象是字段是否存在注解@SensitiveField注解,则将对应字段内容解密,在返回数据到前端阶段判断返回对象字段中是否存在@SensitiveField注解,有则将对应字段内容加密,防止数据泄露。

  • SensitiveMethod 注解添加在方法上
@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SensitiveMethod {


}


  • SensitiveField注解添加到字段上
@Documented
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface  SensitiveField {
}

2.2. 创建切面 SensitiveAspect

SensitiveAspect实现对前端传入后端数据进行解密,以及对后端返回前端数据数据加密

@Slf4j
@Aspect
@Component
public class SensitiveAspect {
    @Autowired
    private StringEncryptor stringEncryptor;
    @Pointcut("@annotation(com.zbbmeta.annotation.SensitiveMethod)")
    public void pointCut() {
    }


    @Around("pointCut()")
    public Object doAround(ProceedingJoinPoint joinPoint ) throws Throwable {


        // 获取参数,对参数中加密字段,进行解密
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
                Field[] fields = arg.getClass().getDeclaredFields();
                for (Field field : fields) {
                    if (field.isAnnotationPresent(SensitiveField.class)) {
                        field.setAccessible(true);
                        Object value = field.get(arg);
                        if (value instanceof String) {
                            // 调用脱敏服务进行处理
                            String maskedValue = stringEncryptor.decrypt((String) value);
                            // 设置脱敏后的值
                            field.set(arg, maskedValue);
                        }
                    }
                }

        }

        Object returnValue = joinPoint.proceed(args);//执行方法获取返回值

        // 获取对象的字段及其值进行加密
        if (returnValue != null) {
            Class<?> clazz = returnValue.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                if(field.isAnnotationPresent(SensitiveField.class)) {
                    field.setAccessible(true);
                    Object value = field.get(returnValue);

                    // 在这里可以对字段值进行处理,例如脱敏
                    if (value instanceof String) {
                        String maskedValue = stringEncryptor.encrypt((String) value);
                        field.set(returnValue, maskedValue);
                    }
                }
            }
        }

        return returnValue;
    }
}

2.3.  使用自定义注解进行标记

  • 在你的实体类中使用@SensitiveField注解标记需要脱敏的字段:
@TableName(value ="tb_tutorial")
@Data
public class Tutorial implements Serializable {
    private Long id;

    private String title;


    @SensitiveField
    private String description;

    private Integer published;

    private static final long serialVersionUID = 1L;
}
  • 在Controller层方法上添加注解
@RestController
@RequestMapping("tutorial")
public class TutorialController {



    @SensitiveMethod
    @PutMapping
    public Tutorial update(@RequestBody Tutorial tutorial){
        System.out.println("tutorial = " + tutorial);
        return tutorial;
    }


    @SensitiveMethod
    @GetMapping
    public Tutorial getTutorial(){

        Tutorial tutorial = new Tutorial();
        tutorial.setTitle("springboot葵花宝典");
        tutorial.setDescription("微信公众号");
        return tutorial;
    }
}


3.测试

配置好上述内容后,启动项目进行测试

  • 获取GET 请求发送http://localhost:8877/tutorial
保护用户隐私:Spring Boot 数据脱敏实战
  • 前端传入加密数据,后端解密PUT请求 http://localhost:8877/tutorial
{
    "id"null,
    "title""springboot葵花宝典",
    "description""D7rG2JHxhwbTd/sdoNJZ4EuKyvOo2DFo",
    "published"null
}

控制台输出如下:发现以及将前端加密数据进行解密

tutorial = Tutorial [Hash = 1228016670, id=null, title=springboot葵花宝典, description=微信公众号, published=null, serialVersionUID=1]

postman响应结果如下:发现返回数据进行加密保护用户隐私:Spring Boot 数据脱敏实战

#代码地址
https://github.com/bangbangzhou/springboot-learn/tree/main/spring-boot-jasypt-demo




如果您觉得本文不错,欢迎关注,点赞,收藏支持,您的关注是我坚持的动力!

原创不易,转载请注明出处,感谢支持!如果本文对您有用,欢迎转发分享!


原文始发于微信公众号(springboot葵花宝典):保护用户隐私:Spring Boot 数据脱敏实战

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/197671.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!