# sensitive-spring-boot-starter **Repository Path**: LevelCoder/sensitive-spring-boot-starter ## Basic Information - **Project Name**: sensitive-spring-boot-starter - **Description**: 接口数据脱敏、加解密springboot starter - **Primary Language**: Java - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 7 - **Created**: 2024-09-29 - **Last Updated**: 2024-09-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 使用说明 ### 1. 介绍 springboot项目中接口返回Vo或接受参数的From中的字段进行脱敏与加解密,该功能生效限于http请求体中数据 (@RequestBody、@ResponseBody),脱敏及加解密可进行扩展,目前只提供了基本的脱敏、加解密功能,更多加密方式后续会完善。 ### 2. 使用方式 git拉取代码到本地, 执行mvn install maven pom引入 ```xml com.security sensitive-spring-boot-starter 0.0.1-SNAPSHOT ``` 启动类上添加@EnableSecurity 该注解上有三个参数,分别为是sensitive否开启脱敏功能、security是否开启加密功能及针对脱敏与加解密类所在的包名,包可不指定,默认为添加@EnableSecurity注解类所在的包的顶级包名+子包名 ``` @SpringBootApplication @EnableSensitive(security = true, sensitive = true, packages = "com.example") public class LeanApplication { public static void main(String[] args) { ConfigurableApplicationContext run = SpringApplication.run(LeanApplication.class, args); } } ``` 在需要的接口上添加@Security注解,对与需要脱敏的字段添加@Sensitive注解,需要加密的字段添加 @Security注解 application.yml 对称加密:AES 密钥请自行生成 ```yaml spring: sensitive: security: type: AES #加密方式,默认AES mode: HEX #加密后的字节数组转为字符串方式:HEX 16进制,BASE64 base64 secret: +6cuvzvyrFZpRG9pf3r7eQ== #加密密钥 密钥请自行生成 charset: UTF-8 maxDeep: 10 #处理脱敏、加解密对象的最大深度,防止相互依赖导致递归栈内存溢出,默认10 ``` 非对称加密:RSA privateKey与publicKey请自行生成 ```yaml sensitive: security: type: RSA mode: HEX charset: UTF-8 maxDeep: 10 publicKey: MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCjE4rpk6aJ996IuX9g3uSXk157aZgreSdW+YzKqFjV1ZxXO6WzcrTXg/EfvHs32bj4UyPmz6S6D+p+9NaUmumbqvWhqSTMtAFRqh0DUK9C0KoRWcNELvnRs4PYOfgeL7UuCVtmimme1tHBRQTcfWK8s0OOio2TAMB6J0s0RMH17QIDAQAB privateKey: MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAKMTiumTpon33oi5f2De5JeTXntpmCt5J1b5jMqoWNXVnFc7pbNytNeD8R+8ezfZuPhTI+bPpLoP6n701pSa6Zuq9aGpJMy0AVGqHQNQr0LQqhFZw0Qu+dGzg9g5+B4vtS4JW2aKaZ7W0cFFBNx9YryzQ46KjZMAwHonSzREwfXtAgMBAAECgYAXGVaM3VgypMSFs1jCnO/eNIamjn96cO/Mlw6FSjFDIL3DcXR4JaBOAqdt6mG9uH5F1mj4caMQo96AWyfl5sd+BjqRKLpmYm6vPEZr6xae3vh8qTAUz/1tzl/fLibsj9GxO+ee8U2jOlLwtO7ip5MLmacZ+TExKPN2ClSGHzJNwQJBANz7noDpAUkg9bPUEsIgYBnfgzRIE2E0PJ1Hc6pHYz7dcLSqtxxN8sacQOViXyLX7OTs1BcjBdzWgccJW4Wb0H0CQQC86uOn35nBYmxC53LYc0824LzQ77RmkigGKs+PfpM1gNCCFh5nObBr7SpV/nGX08bE3EST0KH8GlA+NhYWFqYxAkBdkBuYMQ9eSxo8vXoDv3lw+vWuWSX7bgaMAQiz++3FXDSwCeflkAtOlDHV7USimBGxC6Tw9t8wlZH1F70sYMBxAkEAqBOGtb1u6ymoziFjAQYeDOIHuw/4fWU9bLc78RuY1vojCAmrxQUDXBImH1oAMCc/abfa33O4GjZC/AZcwgwmkQJBAMhrfvra43EEHqOIYveMsqq3bPsXTz2b3W6cTIlL5dKO2BDZsbWRfxSUO4PMVG+STaoa8kR12I/9OZJYGIGOnDo= ``` @Data public class Message { private Integer id; @Sensitive(type = SensitiveTypeEnum.CHINESE_NAME) private String name; @Sensitive(type = SensitiveTypeEnum.ID_CARD) private String idCard; @Sensitive(type = SensitiveTypeEnum.EMAIL) private String email; @Security private String phone; private List companyList; } @Data public class Company { private Integer id; @Sensitive(type = SensitiveTypeEnum.CHINESE_NAME) private String name; @Sensitive(type = SensitiveTypeEnum.ID_CARD) private String code; } @RestController public class SecurityController { @GetMapping("/test") @Security public Message test() { Message message = new Message(); message.setId(1); message.setName("杨哥"); message.setIdCard("610502199323223323"); message.setEmail("907746999@qq.com"); message.setPhone("18712346789"); List companyList = new ArrayList<>(); for (int i = 0; i < 2; i++) { Company company = new Company(); company.setId(i); company.setCode("NO212121212112" + i); company.setName("公司" + i); companyList.add(company); } message.setCompanyList(companyList); return message; } @PostMapping("/test") public Message test(@Security @RequestBody Message message) { return message; } } 效果: GET方式请求test接口 ![image](https://github.com/coder-yangge/sensitive-spring-boot-starter/blob/master/image/test-get.png) Post方式请求test接口 ![image](https://github.com/coder-yangge/sensitive-spring-boot-starter/blob/master/image/test-post.png) ### 3. 扩展 如果想自定义脱敏或者加密可以实现SecurityHandler,具体如下 举例:将字符串长度超过5个字符的字段,超过5个字符的部分使用*替换 如 "中国广东省深圳市南山区某某大厦" 变为 "中国广东省******************************" 1. 自定义注解 ``` /** * @author yangge * @version 1.0.0 * @date 2020/8/31 13:44 */ @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface ISensitive { } ``` 2. 实现SecurityHandler接口,本例中,对添加了ISensitive的字段处理时,如果该字段字符串长度超过5,则将前5个字符保留,后面的全部变为* ``` @Component public class ISensitiveHandler implements SecurityHandler { @Override public boolean support(Field field) { return field.isAnnotationPresent(ISensitive.class); } @Override public ISensitive acquire(Field field) { return field.getAnnotation(ISensitive.class); } @Override public String handleEncrypt(String s, ISensitive iSensitive) { if (s.length() > 5) { String substring = s.substring(0, 5); String target = StringUtils.rightPad(substring, s.length(), "*"); return target; } return s; } @Override public String handleDecrypt(String s, ISensitive iSensitive) { return s; } } ``` ```java @Data public class Message { private Integer id; @Sensitive(type = SensitiveTypeEnum.CHINESE_NAME) private String name; @ISensitive private String idCard; @ISensitive private String email; @Security private String phone; private List companyList; } ``` GET方式请求test接口,返回数据如下,idCard与email字段超过5个字符的部分已替换为* ``` {"id":1,"name":"杨*","idCard":"61050*************","email":"90774***********","phone":"9172d86998be4f0f9c60b886398e18f4","companyList":[{"id":0,"name":"公**","code":"***********1120"},{"id":1,"name":"公**","code":"***********1121"}]} ``` 3. 总结 扩展可以进行脱敏及加解密,此案例为脱敏处理扩展,加密扩展同理,可根据自身加密方式进行加密。