数据分类分级:先摸清家底,再谈安全

做接口安全,我最怕听到一句话:「所有数据都重要,全部加密脱敏」。这听起来很安全,实际上谁也没法落地。

为什么?你想想看,把用户头像和银行卡号用同一套规则处理,性能扛不住,业务也被拖死。说白了,数据分类分级不是安全部门自嗨的文档,而是接口脱敏与加密的前提。家底都没摸清,你保护什么呢?

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 落地实践清单——我建议你这样干

分级这件事,千万不要做成一次性文档。我见过不少团队花两周写了一份漂亮的分级表,然后放文件夹吃灰。

  1. 先扫存量接口:用流量录制或API网关日志,拉出所有字段样本。这一步别怕麻烦,我至少见过5个团队在这一步发现「隐藏的敏感字段」。
  2. 逐字段打标签:每个接口字段贴上类型标签(phone, idcard, bankcard)和定级(L1-L4)。我建议用YAML或JSON配置,别用Excel——不好自动化。
  3. 自动化巡检:写一个简单的CI/CD检查,每次接口变更时自动比对字段标签。如果新增了L3字段但没有加脱敏,直接阻塞发布。
  4. 定期复评:业务在变,数据含义也在变。至少每季度过一遍。我记得有一次复评,发现「用户设备号」因为被用于风控评分,已经从L1升到了L2。

避坑指南:我曾经接手过一个项目,他们把所有L3数据统一用「手机号脱敏规则」处理。结果身份证号脱敏后只剩前3后4,中间8位全星号。嗯……这其实不符合银保监会的监管要求。数据分级必须对应差异化的处理规则,不要偷懒用同一套函数。

2.5 数据分类分级知识框架

下面这张图是我自己梳理的。你看它应该能快速建立本章的全局感:数据分类(识别敏感类型)→ 分级定级(L1-L4)→ 策略映射(脱敏+加密)→ 落地工具(巡检+复评)。这套链路缺一环,落地就会断。

数据分类分级知识框架 数据分类 敏感类型识别 数据分级 L1 ~ L4 定级 策略映射 脱敏 + 加密 落地工具 巡检 + 复评 持续反馈 ⚠️ 级别不是静态的 业务变化 → 重新定级

你看这张图的逻辑:从左到右是先分类再分级,然后映射策略,最后落地工具回馈到分级。那个虚线箭头是「持续反馈」——定级不是拍脑袋,而是落地后不断校准的结果。