• 数据脱敏的六种方案,真香!

数据脱敏的六种方案,真香!

2025-05-19 00:37:06 栏目:宝塔面板 124 阅读

前言

某次新来的同事,在开发环境执行了这样的代码:

// 反例:直接将生产数据同步到测试环境  
public void syncUserToTest(User user) {  
    testDB.insert(user); // 包含手机号、身份证等敏感字段  
}

直接将生产的数据,比如:手机号、身份证等敏感字段,同步到了测试环境。

结果1天后,受到了公司领导的批评。

这个案例揭示了数据脱敏的极端重要性。

这篇文章给大家分享6种常用的数据脱敏方案,希望对你会有所帮助。

方案1:字符串替换(青铜级)

技术原理:通过正则表达式对敏感数据进行部分字符替换

典型代码实现

public class StringMasker {  
    // 手机号脱敏:13812345678 → 138****5678  
    public static String maskMobile(String mobile) {  
        return mobile.replaceAll("(d{3})d{4}(d{4})", "$1****$2");  
    }  

    // 身份证脱敏:110101199003077777 → 1101********7777  
    public static String maskIdCard(String idCard) {  
        if (idCard.length() == 18) {  
            return idCard.replaceAll("(d{4})d{10}(w{4})", "$1****$2");  
        }  
        return idCard; // 处理15位旧身份证  
    }  
}

使用正则表达式将关键字字段替换成了*

适用场景对比

图片

优缺点分析

  • ✅ 优点:实现简单、性能高(时间复杂度O(n))
  • ❌ 缺点:
  • 无法恢复原始数据
  • 正则表达式需考虑多国数据格式差异
  • 存在模式被破解风险(如固定位置替换)

方案2:加密算法(白银级)

加密算法选型

算法类型

代表算法

特点

适用场景

对称加密

AES

加解密快,密钥管理复杂

支付信息存储

非对称加密

RSA

速度慢,安全性高

密钥交换

国密算法

SM4

符合国家标准

政府/金融系统

完整实现示例

public class AESEncryptor {  
    privatestaticfinal String ALGORITHM = "AES/GCM/NoPadding";  
    privatestaticfinalint TAG_LENGTH = 128; // 认证标签长度  

    public static String encrypt(String plaintext, SecretKey key) {  
        byte[] iv = newbyte[12]; // GCM推荐12字节IV  
        SecureRandom random = new SecureRandom();  
        random.nextBytes(iv);  

        Cipher cipher = Cipher.getInstance(ALGORITHM);  
        cipher.init(Cipher.ENCRYPT_MODE, key, new GCMParameterSpec(TAG_LENGTH, iv));  

        byte[] ciphertext = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));  
        return Base64.getEncoder().encodeToString(iv) + ":" +  
               Base64.getEncoder().encodeToString(ciphertext);  
    }  

    // 解密方法类似...  
}

密钥管理方案对比

图片

方案3:数据遮蔽(黄金级)

数据库层实现数据遮蔽

-- 创建脱敏视图  
CREATE VIEW masked_customers AS  
SELECT  
    id,  
    CONCAT(SUBSTR(name,1,1), '***') AS name,  
    CONCAT(SUBSTR(mobile,1,3), '****', SUBSTR(mobile,8,4)) AS mobile  
FROM customers;  

-- 使用列级权限控制  
GRANT SELECT (id, name, mobile) ON masked_customers TO test_user;

创建数据脱敏视图,在视图中将关键字段做遮蔽。

然后在后面需要用到这些字段的代码,需要统一从视图中查询数据。

代理层实现(ShardingSphere示例)

rules:  
-!MASK
tables:
    user:
      columns:
        phone:
          maskAlgorithm:phone_mask
maskAlgorithms:
    phone_mask:
      type:MD5
      props:
        salt:abcdefg123456

性能影响测试数据

数据量

原始查询(ms)

遮蔽查询(ms)

性能损耗

10万

120

145

20.8%

100万

980

1150

17.3%

1000万

10500

12200

16.2%

方案4:数据替换(铂金级)

将原始数据和脱敏的数据保存到cache中,方便后面快速的做转换。

映射表设计

// 使用Guava Cache实现LRU缓存  
LoadingCache dataMapping = CacheBuilder.newBuilder()  
    .maximumSize(100000)  
    .expireAfterAccess(30, TimeUnit.MINUTES)  
    .build(new CacheLoader() {  
        public String load(String key) {  
            return UUID.randomUUID().toString().replace("-", "");  
        }  
    });  

public String replaceData(String original) {  
    return dataMapping.get(original);  
}

替换流程

图片

方案5:动态脱敏(钻石级)

应用层实现(Spring AOP示例)

@Aspect  
@Component
publicclass DataMaskAspect {  

    @Around("@annotation(requiresMasking)")  
    public Object maskData(ProceedingJoinPoint joinPoint, RequiresMasking requiresMasking) throws Throwable {  
        Object result = joinPoint.proceed();  
        return mask(result, requiresMasking.type());  
    }  

    private Object mask(Object data, MaskType type) {  
        if (data instanceof User) {  
            User user = (User) data;  
            switch(type) {  
                case MOBILE:  
                    user.setMobile(MaskUtil.maskMobile(user.getMobile()));  
                    break;  
                case ID_CARD:  
                    user.setIdCard(MaskUtil.maskIdCard(user.getIdCard()));  
                    break;  
            }  
        }  
        return data;  
    }  
}

在需要做数据脱敏的字段上技术RequiresMasking注解,然后在Spring的AOP拦截器中,通过工具类动态实现数据的脱敏。

数据库代理层架构

图片

方案6:K匿名化(王者级)

1. 通俗原理解释

假设医院发布就诊数据:

年龄

性别

疾病

25

感冒

25

发烧

25

骨折

当K=3时,攻击者无法确定具体某人的疾病,因为3人都具有相同特征(25岁男性)。

2. 实现步骤

图片

医疗数据泛化示例

public class KAnonymity {  

    // 年龄泛化:精确值→范围  
    public static String generalizeAge(int age) {  
        int range = 10; // K=10  
        int lower = (age / range) * range;  
        int upper = lower + range - 1;  
        return lower + "-" + upper;  
    }  
}

假设range是K值,等于10。

generalizeAge方法中,通过一定的算法,将年龄的精确值,泛化成一个区间范围。

输入年龄28,返回20-29。

K值选择原则

图片

总结

方案

安全性

性能

可逆性

适用场景

字符串替换

★★

★★★★

不可逆

日志/展示

加密算法

★★★★

★★

可逆

支付信息存储

数据遮蔽

★★★

★★★

部分可逆

数据库查询

数据替换

★★★★

★★

可逆

测试数据生成

动态脱敏

★★★★

★★★

动态可控

生产环境查询

K匿名化

★★★★★

不可逆

医疗/位置数据

下面是某电商平台各方案的使用占比:

图片

苏三的3个核心建议

  1. 数据分类分级:不同级别数据采用不同脱敏策略
  2. 定期审计:使用自动化工具扫描敏感数据泄露
  3. 最小化原则:能不收集的敏感数据坚决不收集

灵魂拷问:当黑客攻破你的数据库时,里面的数据是否像诺基亚功能机一样"防摔"?

安全大礼包

  • 敏感数据扫描工具
  • 脱敏策略检查表
  • 数据安全架构白皮书

本文地址:https://www.yitenyun.com/215.html

搜索文章

Tags

数据库 API FastAPI Calcite 电商系统 MySQL Web 应用 异步数据库 数据同步 ACK 双主架构 循环复制 TIME_WAIT 运维 负载均衡 服务器 管理口 HexHub Docker JumpServer SSL 堡垒机 跳板机 HTTPS 服务器性能 JumpServer安装 堡垒机安装 Linux安装JumpServer SQL 查询 生命周期 Deepseek 宝塔面板 Linux宝塔 锁机制 esxi esxi6 root密码不对 无法登录 web无法登录 行业 趋势 序列 核心机制 Windows Windows server net3.5 .NET 安装出错 HTTPS加密 开源 PostgreSQL 存储引擎 Windows宝塔 Mysql重置密码 宝塔面板打不开 宝塔面板无法访问 查看硬件 Linux查看硬件 Linux查看CPU Linux查看内存 机器学习 Redis Undo Log 机制 Spring 动态查询 响应模型 Oracle 处理机制 InnoDB 数据库锁 优化 万能公式 连接控制 group by 索引 Serverless 无服务器 语言 监控 无法访问宝塔面板 异步化 ES 协同 openHalo scp Linux的scp怎么用 scp上传 scp下载 scp命令 技术 Postgres OTel Iceberg 工具 缓存方案 缓存架构 缓存穿透 国产数据库 高可用 分页查询 数据 主库 SVM Embedding Linux 安全 SQLite-Web SQLite 数据库管理工具 GreatSQL 连接数 Netstat Linux 服务器 端口 存储 云原生 加密 场景 R edis 线程 防火墙 黑客 Recursive R2DBC 启动故障 OB 单机版 向量数据库 大模型 共享锁 SQLark 日志文件 MIXED 3 ​Redis 推荐模型 Canal AI 助手 RocketMQ 长轮询 配置 自定义序列化 PG DBA 不宕机 信息化 智能运维 传统数据库 向量化 向量库 Milvus 业务 Python 同城 双活 线上 库存 预扣 Ftp Hash 字段 Web 接口 开发 聚簇 非聚簇 修改DNS Centos7如何修改DNS IT运维 电商 系统 filelock 分库 分表 Rsync 架构 MySQL 9.3 数据类型 磁盘架构 缓存 mini-redis INCR指令 MongoDB 数据结构 redo log 重做日志 数据分类 MCP 开放协议 sftp 服务器 参数 • 索引 • 数据库 ZODB Doris SeaTunnel 语句 流量 PostGIS 分布式架构 分布式锁​ 窗口 函数 频繁 Codis MVCC Go 数据库迁移 虚拟服务器 虚拟机 内存 工具链 人工智能 推荐系统 数据备份 失效 EasyExcel MySQL8 主从复制 代理 Redisson 锁芯 prometheus Alert MGR 分布式集群 分页 千万级 大表 聚簇索引 非聚簇索引 高效统计 今天这篇文章就跟大家 StarRocks 数据仓库 网络架构 网络配置 引擎 性能 网络故障 播客 崖山 新版本 事务 Java INSERT COMPACT 数据集成工具 发件箱模式 Entity 核心架构 订阅机制 容器 SSH Redka QPS 高并发 Weaviate RDB AOF 关系数据库 Web 数据脱敏 加密算法 B+Tree ID 字段 数据页 Redis 8.0 速度 服务器中毒 Caffeine CP 分布式 集中式 OAuth2 Token 自动重启 Valkey Valkey8.0 DBMS 管理系统 SpringAI 容器化 模型 读写 微软 SQL Server AI功能 原子性 LRU 排行榜 排序 池化技术 连接池 数据字典 兼容性 JOIN 意向锁 记录锁 事务隔离 业务场景 Testcloud 云端自动化 单点故障 UUID ID dbt 数据转换工具 分页方案 排版 部署 日志 1 ReadView 优化器 悲观锁 乐观锁 事务同步 网络 Pottery InfluxDB UUIDv7 主键 AIOPS sqlmock 分布式锁 Zookeeper 对象 仪表盘 RAG HelixDB 产业链 Order 编程 单线程 字典 双引擎 Ansible Pump LLM 拦截器 动态代理 恢复数据 Crash 代码 线程安全 国产 用户 快照读 当前读 视图 IT 订单 List 类型 慢SQL优化 count(*) count(主键) 行数 RR 互联网 表空间 解锁 调优 Next-Key 神经系统 矢量存储 数据库类型 AI代理 CAS 多线程 查询规划 GitHub Git 算法 技巧 并发控制 恢复机制 闪回