敏感字段识别:如何识别PII、PHI等敏感数据
识别敏感字段,是数据令牌化的第一步。你想想看,连哪些数据需要保护都搞不清,后面做再漂亮的令牌方案也是白搭。我在项目中见过不少团队,上来就一股脑把所有字段都打上「敏感」标签,结果令牌化效率极低,业务方天天投诉。
我更倾向于先给敏感数据做个分类。常见的就两类:PII(个人身份信息)和PHI(受保护健康信息)。它们有重叠,但法规要求和处理方式差别不小。
到底什么是PII?
简单说,能直接或间接锁定到某个具体人的信息,都算PII。我个人习惯把它拆成两个层级:
- 直接标识符:姓名、身份证号、手机号、邮箱、社保号、护照号、生物特征数据(指纹、人脸模板)。这些字段一旦暴露,几乎等于「裸奔」。
- 准标识符:性别、出生日期、邮编、民族、职业。单个看好像没什么,但几个拼在一起,结合外部数据也能精准定位到人。我在一次数据脱敏项目里,客户只把姓名和身份证做了令牌化,结果攻击者用「出生日期+邮编+性别」就反推出了其他敏感字段——这事给我上了一课。
识别PII没有一套放之四海而皆准的清单。因为不同地区的法规定义有差异。比如GDPR对PII的定义就比CCPA更宽泛。建议你至少把下面这张表里的字段扫一遍:
| 字段类别 | 典型字段名 | 令牌化优先级 |
|---|---|---|
| 身份标识 | id_card, passport_no, ssn | 最高 |
| 联系方式 | phone, email, wechat_id | 高 |
| 金融信息 | bank_card, credit_card, account_no | 最高 |
| 生物特征 | fingerprint_template, face_encoding | 极高 |
| 地理位置 | gps_coord, ip_address_full | 中 |
| 家庭信息 | family_members, household_income | 中 |
当然,别死抠字段名。我遇到过有些系统把身份证号存成 cert_no 或 id_num,你得靠数据字典和业务理解去匹配。正则表达式是个好抓手,但别全信。
PHI——医疗场景的特殊敏感数据
PHI是HIPAA(美国健康保险可携性与责任法案)里的概念。只要跟个人健康状况、医疗支付、医疗服务相关的字段,都算。我在做医疗数据合规项目时,发现PHI比PII多了一层复杂性——它还包含时序数据和临床上下文。
以下字段务必列入扫描清单:
- 患者姓名、病历号、社保号
- 所有日期(出生、入院、出院、死亡)——注意,年份单独不算,但完整日期就算
- 电话号码、传真号码、邮箱
- 医疗记录编号、健康计划受益人号、账户号
- 生物识别(指纹、声纹、虹膜)
- 全脸照片及其他可识别的图像
- 任何唯一标识码(比如设备序列号结合患者)
PHI识别有个坑:同一份数据在不同场景下敏感度不同。比如「血糖值」在临床研究里是核心字段,必须令牌化;但在实验室质控日志里,如果没有绑定患者ID,可以不加保护。嗯,这里要注意上下文关联。
识别方法——工具与技巧
手动翻数据库表结构不现实,尤其当表数量上千时。我归纳了三种主流方法:
1. 正则表达式扫描
最经典,也最容易被绕过。比如识别身份证号:
# 中国大陆18位身份证号正则(简化版)
身份证模式 ^[1-9]\d{5}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$
# 美国SSN
SSN模式 ^\d{3}-\d{2}-\d{4}$
# 邮箱
邮箱模式 ^[\w\.-]+@[\w\.-]+\.\w+$
但光靠正则不够。我曾经在一个日志文件里找到很多「看起来像」信用卡号的数字,后来发现是订单流水号。这时候需要加一层校验和(Luhn算法)来过滤。
2. 基于命名和元数据的启发式扫描
通过字段名、注释、数据类型来推断。比如字段名叫 email_address,基本可以确定是邮箱。我在一个遗留系统里碰到字段名 fld0123,没注释、没文档,最终只能靠抽样数据反向推断出它是生日字段——这种经验告诉我,数据字典和业务交接文档比任何技术都重要。
3. 机器学习分类器
当字段名和正则都无法覆盖时,可以用NLP模型对字段值进行语义分类。比如训练一个二分类器判断某列是否包含PII。这种方案开销大,但适合大规模、多语言场景。我个人只在客户有几十万张表且人力不足时推荐过,其他情况用前两种方法就够了。
识别流程——一张图讲清楚
下面这张图描述了我常用的敏感字段识别与分类流程。你可以对照自己的项目走一遍:
PHI与PII的异同——一张表看清
| 维度 | PII | PHI |
|---|---|---|
| 核心法规 | GDPR, CCPA, 个保法 | HIPAA, HITECH |
| 涵盖范围 | 任何可识别身份的信息 | 仅限于健康相关数据 |
| 常见字段 | 姓名、身份证号、邮箱、电话 | 病历号、诊断结果、实验室检查值 |
| 去标识化要求 | 匿名化/假名化 | Safe Harbor / Expert Determination |
| 时间维度 | 一般不考虑时间序列 | 日期(入院/出院)也是敏感字段 |
| 重识别风险 | 中等(依赖准标识符组合) | 高(尤其基因、罕见病例) |
自动化识别的几个关键点
如果你的系统字段数超过5000,手动打标基本不现实。我推荐按这个顺序推进自动化:
- 建敏感数据字典:把所有已知的敏感字段名、正则模式、校验逻辑汇总成一份可扩展的规则库。
- 元数据爬取:用SQL直接查information_schema或数据湖的catalog,拿到所有字段名、注释、数据类型。
- 批量正则扫描:对每个字段的值做抽样(推荐100条以上),命中模式则标记。
- 结果确认与反馈:让数据所有者审核标记结果,纠正的样本反哺规则库。
我这么干过一次,原本两周的识别工作压缩到3天完成。关键还是前期规则库要扎实,别指望一次性完美。
识别完成后,你就可以进入下一阶段——对敏感字段应用令牌化策略了。不过那又是另一个话题了。今天咱们先把这个基础打牢,后面走起来才稳当。