数据分类分级:先摸清家底,再谈安全
做接口安全,我最怕听到一句话:「所有数据都重要,全部加密脱敏」。这听起来很安全,实际上谁也没法落地。
为什么?你想想看,把用户头像和银行卡号用同一套规则处理,性能扛不住,业务也被拖死。说白了,数据分类分级不是安全部门自嗨的文档,而是接口脱敏与加密的前提。家底都没摸清,你保护什么呢?
2.1 敏感数据类型识别——你得知道哪些东西不能裸奔
我刚开始做安全时,也掉进过一个坑:把「敏感数据」想得太简单。总觉得用户手机号、身份证号是敏感数据,其他无所谓。直到有一次生产环境脱敏漏了用户的设备指纹……嗯,那场面挺尴尬的。
其实,敏感数据类型可以分为几大类。我个人习惯用一个「4+2」模型来识别:
| 大类 | 典型数据项 | 泄露影响 |
|---|---|---|
| 个人身份信息(PII) | 姓名、身份证号、护照号、住址 | 身份盗用、精准诈骗 |
| 财务信息 | 银行卡号、支付密码、交易流水 | 资金损失、金融欺诈 |
| 健康信息 | 病历、体检报告、基因数据 | 隐私暴露、歧视风险 |
| 生物特征 | 指纹、人脸特征、声纹 | 不可逆泄露、认证突破 |
| 行为与偏好(+) | 浏览记录、购物习惯、位置轨迹 | 画像泄露、定向骚扰 |
| 系统与业务数据(+) | 、数据库连接串、用户鉴权 | 系统入侵、越权访问 |
注意最后两类——「行为与偏好」和「系统业务数据」。很多团队只盯着PII,结果明文传出去了,整个系统被拖库。
识别方法:我建议你直接拉出所有接口的请求/响应报文,逐字段打标签。不用全人工,可以用正则匹配模式:身份证号用\d{17}[\dXx],银行卡用\d{16,19}。先扫一轮,再人工复核。
// 一个简单的敏感字段识别配置示例(YAML)
sensitive_patterns:
- name: "身份证号"
pattern: "\d{17}[\dXx]"
level: "high"
- name: "手机号"
pattern: "1[3-9]\d{9}"
level: "high"
- name: "银行卡号"
pattern: "\d{16,19}"
level: "critical"
- name: "IP地址"
pattern: "\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
level: "low" // 注意:IP本身不算极高敏感,但结合其他数据时升级
2.2 分级标准归纳总结——不是所有数据都配得上最高防护
识别的下一步是分级。分级标准不能拍脑袋,得兼顾法规要求、业务影响、泄露后果三个维度。我见过有些公司直接照搬GDPR的分类,结果内部流程跑不动。你想想,一个退款异常日志里的用户ID,和用户登录密码,能是同一个级别吗?
我个人在实践中常用四级分级法,它跟接口脱敏与加密的策略能天然对齐:
| 级别 | 定义 | 典型数据 | 脱敏策略 | 加密策略 |
|---|---|---|---|---|
| L4 - 极机密 | 泄露即致命,不可逆伤害 | 支付密码、私钥、人脸特征 | 禁止脱敏展示,仅存摘要 | 强制加密(AES-256 + 国密SM4) |
| L3 - 高敏感 | 泄露导致重大损失或违规 | 身份证号、银行卡、病历 | 动态脱敏(保留格式) | 传输加密 + 存储加密 |
| L2 - 中敏感 | 泄露造成一定影响但不致命 | 手机号、邮箱、家庭住址 | 部分脱敏(如 138****1234) | 传输加密(TLS 1.3) |
| L1 - 低敏感 | 泄露基本无害或已公开 | 用户名、非唯一标签、匿名ID | 可选脱敏 | 传输加密即可 |
一点经验:L4数据在接口中几乎不应该出现明文。如果业务一定要用——比如支付验证——那也得用化替换。我曾经帮一个金融项目回滚过接口方案,就是因为他们在回执里传了完整的CVV码。
2.3 分级如何指导脱敏与加密——打通策略的最后一公里
分级不是终点,是起点。如果你只做到「哦,这是L3数据」,但接口里还是原样传,那跟没分级一样。
我习惯用一张策略映射矩阵来落地。说白了,就是给每个数据级别配上固定的处理动作:
// 策略映射伪代码
function decideStrategy(dataLevel, fieldType):
if dataLevel == L4:
return { encryption: "AES-256-GCM", mask: false, tokeniz: true }
if dataLevel == L3:
return { encryption: "TLS + field-level enc", mask: "dynamic", tokeniz: false }
if dataLevel == L2:
return { encryption: "TLS", mask: "partial", tokeniz: false }
if dataLevel == L1:
return { encryption: "TLS", mask: "none", tokeniz: false }
这里有个坑:数据的级别不是一成不变的。一个用户ID在A接口里只是查询参数,属于L1;但到了B接口里跟身份证号拼接查询,它就升级为L2甚至L3。我在项目中遇到过,某个团队把userId一直当L1处理,结果在日志上下文里跟手机号一起输出,间接泄露了用户关联关系。
2.4 落地实践清单——我建议你这样干
分级这件事,千万不要做成一次性文档。我见过不少团队花两周写了一份漂亮的分级表,然后放文件夹吃灰。
- 先扫存量接口:用流量录制或API网关日志,拉出所有字段样本。这一步别怕麻烦,我至少见过5个团队在这一步发现「隐藏的敏感字段」。
- 逐字段打标签:每个接口字段贴上类型标签(phone, idcard, bankcard)和定级(L1-L4)。我建议用YAML或JSON配置,别用Excel——不好自动化。
- 自动化巡检:写一个简单的CI/CD检查,每次接口变更时自动比对字段标签。如果新增了L3字段但没有加脱敏,直接阻塞发布。
- 定期复评:业务在变,数据含义也在变。至少每季度过一遍。我记得有一次复评,发现「用户设备号」因为被用于风控评分,已经从L1升到了L2。
避坑指南:我曾经接手过一个项目,他们把所有L3数据统一用「手机号脱敏规则」处理。结果身份证号脱敏后只剩前3后4,中间8位全星号。嗯……这其实不符合银保监会的监管要求。数据分级必须对应差异化的处理规则,不要偷懒用同一套函数。
2.5 数据分类分级知识框架
下面这张图是我自己梳理的。你看它应该能快速建立本章的全局感:数据分类(识别敏感类型)→ 分级定级(L1-L4)→ 策略映射(脱敏+加密)→ 落地工具(巡检+复评)。这套链路缺一环,落地就会断。
你看这张图的逻辑:从左到右是先分类再分级,然后映射策略,最后落地工具回馈到分级。那个虚线箭头是「持续反馈」——定级不是拍脑袋,而是落地后不断校准的结果。