数据脱敏:写给初学者的通俗解释
前几天帮朋友排查他们测试环境的一个问题,顺手查了张用户表,好家伙,几十万条真实的手机号和身份证号直接躺在里面。一问才知道,是当初图省事从生产库整库导出来的。我说你们这么搞,测试库权限一放开,等于全公司都能看到用户隐私,出了事都没地儿哭去。后来跟他聊了半天数据脱敏,这篇就把那天聊的东西整理一下,写给刚入行的同学,懂的可以直接关了。
到底什么是数据脱敏
说白了,数据脱敏就是给数据“打码”,但打完码数据还得能用。最直观的例子就是手机号:
13812345678 → 138****5678
注意右边这个既不是加密也不是删除,就是变形了:格式还是手机号的格式,前三位后四位都还在,测试的时候该做格式校验照样能校验,但谁也拼不回真实号码。
本质上跟你发截图前给头像打个码是一回事,只不过数据库里动辄几十万条,总不能一条条手动糊,所以得靠程序批量处理。常见的敏感数据还有身份证、银行卡号、住址、邮箱这些,思路都一样。
静态脱敏和动态脱敏
这俩词听起来唬人,其实不难分。
静态脱敏:把数据从生产库导出来,批量打码,再灌进测试库。生产库原封不动,测试库里全是假数据。绝大多数公司用的都是这种,改造成本也最低。
动态脱敏:数据压根不动,还躺在生产库里,只是不同的人查出来的东西不一样,DBA 查是真实的,普通开发查出来自动就是打码后的。这玩意儿一般得靠数据库代理或者中间件去拦查询,小团队基本不会上,知道有这回事就行。
常见的几种套路
打码的方式不止一种,按需求挑:
- 掩码:保留一部分,其余用
*替换,比如姓名“张三”变“张*”。最简单,也最常见。 - 替换:用一条假数据顶掉真实数据,比如把真实姓名换成随机生成的假名。好处是长度格式都自然,灌进测试库看起来更像那么回事。
- 哈希:比如对手机号做一次 SHA256。适合需要“对得上号”的场景,同一个手机号不管出现在哪张表里,哈希完都是同一个值,join 的时候还能关联上。
- 置空:直接置成
NULL,简单粗暴,不重要的字段这么干最省事。 - 日期偏移:出生日期整体平移随机几天,真实生日看不见了,但年龄分布大体还在,做统计分析够用。
一个 Python 版的手机号掩码,几行的事:
def mask_phone(phone: str) -> str:
return phone[:3] + "****" + phone[-4:]
print(mask_phone("13812345678")) # 138****5678
实际做的时候一般不自己手写这些,主流数据库多少都有现成方案(MySQL 企业版有脱敏插件,PostgreSQL 有 anon 扩展之类的),先看看自带的(没准儿你们公司内部已经有现成工具了,先问问再动手),别急着造轮子。
几个容易踩的坑
别只盯着单个字段打码。 手机号、姓名、住址,单看每一个还好,凑一块儿基本就能锁定一个人了。动手前把表结构过一遍,想想哪几个字段组合起来能对上真人。
哈希不等于安全。 手机号总共就 11 位,拿到哈希值暴力跑一遍全部号码就能反推回来。真要用哈希就加盐,不然不如老老实实掩码。
别忘了日志。 库里的数据脱得干干净净,结果日志里把完整请求参数打出来了,等于白干。日志也是数据,也得脱。
想清楚脱敏后的数据还要干嘛。 比如测试要验证短信登录,手机号全打码了,短信发给谁去?这种就得提前备一批专门的测试号码,别等测试同学找上门了才想起来。
写在最后
数据脱敏这事,说穿了就是个“打码”的活儿,技术含量不算高,难的是想得全不全面。核心就一句话:数据可以给别人用,但不能让别人看到真东西。先从最简单的掩码做起,把测试库里的真实数据清掉,这一步就已经比很多公司走得靠前了...
评论
还没有评论。
发表评论
提交后评论将经过自动审核,审核通过后公开展示。