档案管理系统敏感数据全场景脱敏实操落地完整解决方案
方案选型说明
档案管理系统同时存在已入库的存量敏感档案和新增的增量档案,本方案采用静态脱敏+动态脱敏结合的架构:静态脱敏处理存量历史数据,动态脱敏处理新增数据接口输出,满足权限分级查看需求,无需改动原有业务架构。
前期准备工作
1. 依赖引入
本方案使用开源免费的敏感数据脱敏工具,绝大多数Java架构的档案系统可以直接引入Maven依赖,无需额外部署服务,依赖坐标如下,直接复制到pom.xml即可:
```如果是非Java项目,可以直接使用开源工具DataMasker,下载地址:https://github.com/edmund-wagner/datamasker,可直接本地运行处理数据。
2. 敏感字段梳理
提前梳理系统内所有需要脱敏的字段和对应规则,常见梳理结果如下:
- 个人敏感类:姓名(保留首字,其余打码)、手机号(保留前3后4)、身份证号(保留前6后4)、银行卡号(保留前6后4)
- 档案涉密类:联系人邮箱、单位内部地址、涉密档案文号(保留前4后2,中间打码)
存量档案数据脱敏实操
强制操作第一步:备份全库,避免数据丢失,执行以下命令完成备份
``` mysqldump -u[你的数据库用户名] -p [你的档案库名] > archive_backup_`date +%Y%m%d`.sql ```备份完成后,通过工具生成脱敏更新SQL,再执行SQL完成存量数据修改,示例可直接运行的Java代码如下,替换对应连接信息即可使用:
``` import com.github.houbb.sensitive.core.SensitiveUtil; import com.github.houbb.sensitive.core.strategy.impl.; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.Statement; import java.io.FileWriter; public class ArchiveStaticDesense { public static void main(String[] args) throws Exception { // 替换为你自己的数据库信息 String url = "jdbc:mysql://127.0.0.1:3306/你的库名?useSSL=false&characterEncoding=utf8&serverTimezone=Asia/Shanghai"; String dbUser = "root"; String dbPwd = "你的数据库密码"; // 加载驱动连接数据库 Class.forName("com.mysql.cj.jdbc.Driver"); Connection conn = DriverManager.getConnection(url, dbUser, dbPwd); Statement stmt = conn.createStatement(); // 替换为你的档案表名和字段名 ResultSet rs = stmt.executeQuery("select id,real_name,phone,id_card from user_archive"); // 生成脱敏SQL文件 FileWriter fw = new FileWriter("archive_desense_update.sql"); while (rs.next()) { Long id = rs.getLong("id"); // 按自定义规则脱敏 String name = SensitiveUtil.desensitive(rs.getString("real_name"), new NameStrategy()); String phone = SensitiveUtil.desensitive(rs.getString("phone"), new PhoneStrategy()); String idCard = SensitiveUtil.desensitive(rs.getString("id_card"), new IdCardStrategy()); // 生成更新语句 String updateSql = String.format("update user_archive set real_name='%s',phone='%s',id_card='%s' where id=%d;\n", name, phone, idCard, id); fw.write(updateSql); } // 关闭资源 fw.close(); rs.close(); stmt.close(); conn.close(); System.out.println("脱敏SQL生成完成,文件路径:当前项目根目录/archive_desense_update.sql"); } } ```
运行上述代码生成SQL后,执行以下命令完成数据更新:
``` mysql -u[你的用户名] -p [你的库名] < archive_desense_update.sql ```执行完成后,随机抽取10条数据验证脱敏结果是否符合规则即可。
增量档案动态脱敏实操
动态脱敏不修改数据库原始数据,仅在接口返回时根据用户权限脱敏,适合档案系统分级授权查看的场景,配置步骤如下:
1. 实体类加脱敏注解
在档案实体类的对应敏感字段上添加@Sensitive注解,指定脱敏策略即可,示例如下:
``` import com.github.houbb.sensitive.annotation.Sensitive; import com.github.houbb.sensitive.core.strategy.impl.; public class UserArchive { private Long id; @Sensitive(strategy = NameStrategy.class) private String realName; @Sensitive(strategy = PhoneStrategy.class) private String phone; @Sensitive(strategy = IdCardStrategy.class) private String idCard; @Sensitive(strategy = ArchiveNoStrategy.class) private String archiveNo; // getter、setter省略 } ```如果需要自定义脱敏策略,只需实现SensitiveStrategy接口,示例如下:
``` import com.github.houbb.sensitive.api.SensitiveStrategy; public class ArchiveNoStrategy implements SensitiveStrategy { @Override public Object desensitize(Object origin) { if (origin == null) return null; String str = origin.toString(); if (str.length() <= 6) return str; // 保留前4后2,中间打码 return str.substring(0, 4) + "" + str.substring(str.length() - 2); } } ```2. 权限控制配置
如果需要给管理员放行,返回原始数据,只需在接口层添加开关,代码示例:
``` // 根据当前用户权限控制脱敏开关 if (currentUser.isAdmin()) { SensitiveUtil.switchOff(); } else { SensitiveUtil.switchOn(); } ```配置完成后,所有查询接口会自动按照权限返回对应结果,无需修改其他业务代码。
结果验证与问题排查
- 验证步骤1:存量数据:登录数据库随机查询,核对脱敏格式是否符合预期,例如手机号是否为1351234格式
- 验证步骤2:增量数据:分别用普通用户和管理员访问新增档案接口,核对普通用户返回脱敏数据,管理员返回原始数据
- 问题1:脱敏后原始数据丢失:使用开头生成的备份文件执行恢复命令:
mysql -u用户名 -p 库名 < archive_backup_xxxx.sql,检查SQL生成逻辑后重新操作 - 问题2:接口不生效脱敏:检查实体类是否添加@Sensitive注解,starter是否已经注入到Spring容器,依赖是否引入正确