跨数据库敏感字段列遮蔽与访问保护 - 第3节
三、列遮蔽核心原理:遮蔽算法基础
聊到列遮蔽,很多人第一反应就是「把数据藏起来」。但怎么藏?藏到什么程度?跟加密有什么区别?这些才是真正要搞明白的。我做了这么多年数据安全,见过太多项目在遮蔽策略上栽跟头——说白了,就是没搞懂最基础的遮蔽算法。
今天咱们就把这块掰开揉碎了讲。你想想看,遮蔽算法其实就三大类:替换、混淆、截断。掌握了这三板斧,大部分场景都能应付。
3.1 替换算法
替换,顾名思义,就是用假数据换掉真数据。这是最直观的遮蔽方式。
我个人习惯把替换分成两种:静态替换和动态替换。
- 静态替换:提前准备好一个假数据池子,每次遮蔽时从里面随机取一个。比如把真实姓名换成「张三」「李四」「王五」这种。
- 动态替换:根据某种规则实时生成假数据。比如保留手机号的前三位和后四位,中间四位随机生成。
核心要点:替换后的数据必须保持业务可用性。比如遮蔽后的手机号,格式还得是手机号,不能变成乱码。
我在项目中遇到过一件事:有个团队做测试环境遮蔽,把身份证号全部替换成「123456789012345678」。结果测试用例里有个校验身份证号长度的逻辑,直接炸了。为什么?因为真实身份证号是18位,他们替换成18个1,长度没问题,但校验位算法过不去。嗯,这就是典型的替换没考虑业务语义。
# 一个简单的静态替换示例
import random
fake_names = ['张伟', '王芳', '李娜', '刘洋', '陈静']
def mask_name(real_name):
return random.choice(fake_names)
# 动态替换:保留手机号前3后4
def mask_phone(phone):
return phone[:3] + '****' + phone[-4:]
3.2 混淆算法
混淆比替换要「聪明」一点。它不是简单换掉,而是让数据变得难以辨认,但保留某些统计特征或结构特征。
举个例子:把工资字段乘以一个随机系数,再四舍五入。这样分析人员能看到大概的薪资分布,但拿不到精确数字。我曾经帮一家金融公司做过这种方案——他们需要对外发布行业薪酬报告,但又不能泄露具体员工的工资。
混淆的常见手法包括:
- 数值扰动:在原值上加一个随机偏移量
- 字符重排:打乱字符串中的字符顺序
- 格式保留混淆:保持数据格式不变,但内容变得不可识别
小技巧:混淆的强度要可控。太弱了容易被还原,太强了数据就废了。我一般建议保留原始数据的标准差在±5%以内。
3.3 截断算法
截断最简单,也最暴力。直接把敏感部分砍掉。
比如信用卡号只保留后四位,前面的全部用星号代替。或者身份证号只显示前六位和后四位,中间八位隐藏。
截断的好处是速度快、实现简单。但缺点也很明显——信息丢失严重。你想想看,如果把手机号截断成前三位,那跟没遮蔽差不多(前三位是号段,公开信息)。但如果只保留后四位,又没法用来做业务关联。
注意:截断不是万能的。有些场景下,截断后的数据仍然可以通过关联分析还原出部分敏感信息。我曾经见过一个案例,某公司把用户邮箱截断成「@」前面的首字母和后面的域名,结果攻击者通过社交工程补全了完整邮箱。
遮蔽粒度控制
算法选好了,接下来要决定「遮多少」。这就是遮蔽粒度的问题。我把它分成三个层次:全遮蔽、部分遮蔽、动态遮蔽。
| 粒度类型 | 定义 | 典型场景 | 风险等级 |
|---|---|---|---|
| 全遮蔽 | 完全替换或隐藏整个字段 | 密码、密钥、支付密码 | 最高 |
| 部分遮蔽 | 只遮蔽字段中的敏感部分 | 手机号、身份证号、邮箱 | 中等 |
| 动态遮蔽 | 根据用户权限或上下文决定遮蔽程度 | 客服系统、审计日志 | 灵活 |
3.4 全遮蔽
全遮蔽就是「一刀切」。不管你是谁,看到的数据都是假的或者空的。
这种策略最安全,但也最影响使用。比如在数据分析场景,如果把所有用户姓名都全遮蔽成「***」,那分析人员就没法做用户分群了。
我个人建议:全遮蔽只用于不需要原始值的场景。比如密码存储、密钥管理、支付令牌。
3.5 部分遮蔽
部分遮蔽是实际项目中最常用的策略。它只遮蔽敏感信息中的一部分,保留业务需要的部分。
举个例子:
- 手机号:138****1234
- 身份证号:110101****1234
- 邮箱:zh***@example.com
这样做的好处是:数据仍然有辨识度,可以用于业务关联,但敏感信息被保护了。
我记得有一次做电商平台的订单导出功能。运营人员需要看到用户的收货地址来做区域分析,但又不能暴露完整地址。最后我们用了部分遮蔽——保留省市区,遮蔽街道和门牌号。运营能分析出「北京朝阳区订单最多」,但拿不到具体门牌号。
3.6 动态遮蔽
动态遮蔽是进阶玩法。它根据访问者的身份、权限、甚至访问时间来决定遮蔽的粒度。
比如:
- 客服人员:可以看到用户手机号的后四位,用于核对身份
- 运营人员:只能看到手机号的归属地,不能看到完整号码
- 系统管理员:在审计日志中看到完整手机号,但操作会被记录
动态遮蔽的实现通常需要结合访问控制策略。我在一个政府项目中做过这种方案——不同级别的公务员查看公民信息时,看到的遮蔽程度不一样。级别越高,看到的信息越完整。但所有查看行为都会被记录,方便事后审计。
关键点:动态遮蔽不是技术问题,而是管理问题。你需要先定义清楚「什么人能看到什么数据」,然后才是技术实现。
遮蔽与加密的区别
这个问题我几乎每次培训都会被问到。很多人觉得「遮蔽不就是加密吗?都是把数据变乱」。其实完全不是一回事。
我画了一张图,帮你理清两者的关系:
说白了,遮蔽和加密的目标不同:
- 遮蔽:让数据变得不可识别,但保持可用性。遮蔽后的数据不能再还原回去。
- 加密:让数据变得不可读,但可以通过密钥还原。加密后的数据通常不能直接用于业务操作。
我举个例子你就明白了。假设你有一张信用卡号:6222****1234。
- 遮蔽后:6222****1234(保留前4后4,中间遮蔽)。这个数据可以直接展示在客服界面上,客服能用来核对身份,但拿不到完整卡号。
- 加密后:AES-256加密后的二进制数据。这个数据只能存储在数据库里,展示出来是一堆乱码,谁看了都没用。
避坑指南:我曾经见过一个项目,把用户手机号用AES加密后存到数据库,然后每次查询时解密展示。结果数据库查询性能直接下降了80%。为什么?因为加密后的数据没法建索引,每次查询都要全表扫描。如果当时用遮蔽,保留前三位和后四位,中间用星号,既能保护隐私,又能正常建索引。
所以我的建议是:
- 需要还原的场景 → 用加密(比如数据传输、存储)
- 不需要还原的场景 → 用遮蔽(比如测试数据、分析数据、展示数据)
- 两者可以结合使用:存储时加密,展示时遮蔽
嗯,这就是遮蔽算法的核心原理。你想想看,掌握了替换、混淆、截断这三种基础算法,再配合全遮蔽、部分遮蔽、动态遮蔽这三种粒度控制,大部分数据保护场景都能覆盖。至于遮蔽和加密的区别,记住一句话:遮蔽是毁掉数据,加密是锁住数据。选哪个,取决于你的业务需求。