news 2026/6/13 18:20:00

【架构实战】数据脱敏与隐私保护:合规是底线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【架构实战】数据脱敏与隐私保护:合规是底线

一、日志里打印了用户手机号,被安全部门约谈

2021年,安全部门扫描发现我们的日志里明文打印了用户手机号和身份证号。

根据《个人信息保护法》,这属于违规行为。我们被要求限期整改,否则面临罚款。

从那以后,数据脱敏成了我们的必修课。


二、脱敏规则

/** * 脱敏工具类 */publicclassMaskUtils{/** 手机号脱敏:138****1234 */publicstaticStringmaskPhone(Stringphone){if(phone==null||phone.length()<7)returnphone;returnphone.substring(0,3)+"****"+phone.substring(phone.length()-4);}/** 身份证脱敏:3301****1234 */publicstaticStringmaskIdCard(StringidCard){if(idCard==null||idCard.length()<8)returnidCard;returnidCard.substring(0,4)+"****"+idCard.substring(idCard.length()-4);}/** 邮箱脱敏:t***@example.com */publicstaticStringmaskEmail(Stringemail){if(email==null||!email.contains("@"))returnemail;String[]parts=email.split("@");returnparts[0].charAt(0)+"***@"+parts[1];}/** 姓名脱敏:张** */publicstaticStringmaskName(Stringname){if(name==null||name.length()<2)returnname;returnname.charAt(0)+"**";}/** 银行卡脱敏:**** **** **** 1234 */publicstaticStringmaskBankCard(StringcardNo){if(cardNo==null||cardNo.length()<4)returncardNo;return"**** **** **** "+cardNo.substring(cardNo.length()-4);}/** 地址脱敏:浙江省杭州市**** */publicstaticStringmaskAddress(Stringaddress){if(address==null||address.length()<6)returnaddress;returnaddress.substring(0,6)+"****";}}

2.1 MyBatis脱敏拦截器

/** * 查询结果自动脱敏 */@Intercepts({@Signature(type=Executor.class,method="query",args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})})@ComponentpublicclassDataMaskInterceptorimplementsInterceptor{@OverridepublicObjectintercept(Invocationinvocation)throwsThrowable{Objectresult=invocation.proceed();if(resultinstanceofList){for(Objectitem:(List<?>)result){maskSensitiveFields(item);}}elseif(result!=null){maskSensitiveFields(result);}returnresult;}privatevoidmaskSensitiveFields(Objectobj){if(obj==null)return;for(Fieldfield:obj.getClass().getDeclaredFields()){Sensitivesensitive=field.getAnnotation(Sensitive.class);if(sensitive!=null&&field.getType()==String.class){field.setAccessible(true);try{Stringvalue=(String)field.get(obj);if(value!=null){field.set(obj,maskByType(value,sensitive.type()));}}catch(IllegalAccessExceptione){// ignore}}}}privateStringmaskByType(Stringvalue,SensitiveTypetype){switch(type){casePHONE:returnMaskUtils.maskPhone(value);caseID_CARD:returnMaskUtils.maskIdCard(value);caseEMAIL:returnMaskUtils.maskEmail(value);caseNAME:returnMaskUtils.maskName(value);caseBANK_CARD:returnMaskUtils.maskBankCard(value);caseADDRESS:returnMaskUtils.maskAddress(value);default:returnvalue;}}}/** * 敏感字段注解 */@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public@interfaceSensitive{SensitiveTypetype();}// 使用@DatapublicclassUserVO{privateLongid;privateStringusername;@Sensitive(type=SensitiveType.PHONE)privateStringphone;@Sensitive(type=SensitiveType.ID_CARD)privateStringidCard;@Sensitive(type=SensitiveType.EMAIL)privateStringemail;}

三、日志脱敏

/** * 日志脱敏拦截器 */@ComponentpublicclassLogMaskFilterimplementsFilter{@OverridepublicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,FilterChainchain)throwsIOException,ServletException{ContentCachingRequestWrapperwrappedRequest=newContentCachingRequestWrapper((HttpServletRequest)request);chain.doFilter(wrappedRequest,response);// 日志中记录请求体(脱敏后)Stringbody=newString(wrappedRequest.getContentAsByteArray());Stringmasked=maskSensitiveData(body);log.info("Request: uri={}, body={}",((HttpServletRequest)request).getRequestURI(),masked);}privateStringmaskSensitiveData(Stringdata){// 正则匹配手机号data=data.replaceAll("(1[3-9]\\d)\\d{4}(\\d{4})","$1****$2");// 正则匹配身份证号data=data.replaceAll("(\\d{4})\\d{10}(\\d{4})","$1**********$2");// 正则匹配邮箱data=data.replaceAll("(\\w)\\w+(@\\w+\\.\\w+)","$1***$2");returndata;}}

四、加密存储

/** * 数据库字段加密 */@ComponentpublicclassFieldEncryptUtil{@AutowiredprivateAesEncryptoraesEncryptor;/** * 加密 */publicStringencrypt(Stringplaintext){returnaesEncryptor.encrypt(plaintext);}/** * 解密 */publicStringdecrypt(Stringciphertext){returnaesEncryptor.decrypt(ciphertext);}}/** * MyBatis加密拦截器 */@Intercepts({@Signature(type=Executor.class,method="update"),@Signature(type=Executor.class,method="query")})@ComponentpublicclassFieldEncryptInterceptorimplementsInterceptor{@AutowiredprivateFieldEncryptUtilencryptUtil;@OverridepublicObjectintercept(Invocationinvocation)throwsThrowable{// 写入时加密if("update".equals(invocation.getMethod().getName())){encryptParams(invocation.getArgs());}Objectresult=invocation.proceed();// 查询时解密if("query".equals(invocation.getMethod().getName())){decryptResult(result);}returnresult;}}

五、踩坑实录

坑1:脱敏了但数据库里没加密

API返回脱敏了,但数据库里是明文存储,被SQL注入后泄露。

解决:敏感字段数据库加密存储。

坑2:脱敏规则不统一

不同服务的脱敏方式不同,A服务手机号3位+4位,B服务4位+4位。

解决:统一脱敏工具类,强制使用。

坑3:日志脱敏遗漏

有些日志是第三方库打印的,没有经过我们的脱敏过滤器。

解决:Logback脱敏插件,统一处理所有日志输出。

坑4:加密后无法查询

手机号加密存储后,无法按手机号查询。

解决:存储脱敏值+加密值,用脱敏值查询;或使用可搜索加密。

坑5:密钥管理

加密密钥硬编码在代码里,不安全。

解决:密钥存储在KMS(密钥管理服务),运行时动态获取。


六、总结

数据隐私保护要点:

层面方案
传输HTTPS + 字段加密
存储数据库字段加密
展示脱敏返回
日志自动脱敏
密钥KMS管理

血的教训:

数据安全不是可选项。一次数据泄露的代价,远超安全建设的成本。

思考题:你的系统做了哪些数据脱敏措施?


个人观点,仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 3:24:56

做好“答案胶囊“,你的AI引用率可以提升40%

概述 你有没有遇到过这种情况&#xff1a;你的网站 SEO 排名不错&#xff0c;但在问 ChatGPT "XX品牌怎么样"时&#xff0c;AI 推荐的全是竞品&#xff1f;这不是 SEO 的问题——AI 搜索引擎找的不是"排名最高的页面"&#xff0c;而是"最容易直接引用…

作者头像 李华
网站建设 2026/6/14 4:08:49

从无人机到平衡车:聊聊FOC算法里的SVPWM,如何影响你的电机响应和续航

从无人机到平衡车&#xff1a;FOC算法中的SVPWM如何重塑电机性能体验 当你的无人机在急速爬升时突然动力迟滞&#xff0c;或是电动滑板车在加速瞬间发出刺耳的啸叫声&#xff0c;背后可能都藏着同一个技术细节——SVPWM调制策略的选择。这个隐藏在电机控制器深处的算法&#xf…

作者头像 李华
网站建设 2026/6/14 7:45:51

终极免费游戏串流指南:如何用Sunshine搭建自托管游戏服务器

终极免费游戏串流指南&#xff1a;如何用Sunshine搭建自托管游戏服务器 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 你是否曾想过在客厅的电视上玩PC大作&#xff0c;或者在外出…

作者头像 李华
网站建设 2026/6/14 7:47:00

图论强连通分量与拓扑排序:依赖分析与任务调度的底层逻辑

图论强连通分量与拓扑排序&#xff1a;依赖分析与任务调度的底层逻辑 一、依赖关系的"循环陷阱"&#xff1a;为什么构建系统会卡死 软件工程中&#xff0c;依赖关系无处不在——模块间的编译依赖、任务间的执行依赖、服务间的调用依赖。当依赖关系形成环时&#xff0…

作者头像 李华
网站建设 2026/6/14 7:46:08

5分钟网页转应用终极指南:PakePlus让你告别复杂配置

5分钟网页转应用终极指南&#xff1a;PakePlus让你告别复杂配置 【免费下载链接】PakePlus Turn any webpage/HTML/Vue/React and so on into desktop and mobile app under 5M with easy in few minutes. 轻松将任意网站/HTML/Vue/React等项目构建为轻量级(小于5M)多端桌面应用…

作者头像 李华
网站建设 2026/6/14 7:46:08

题解:AcWing 4920 乘法谜题

本文分享的必刷题目是从蓝桥云课、洛谷、AcWing等知名刷题平台精心挑选而来&#xff0c;并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构&#xff0c;旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。 欢迎大…

作者头像 李华