一、为什么数据分类分级是脱敏的前置条件
很多团队做数据库安全时,第一步就直接上加密或者上脱敏,结果很快遇到两类典型问题。
第一类问题叫"一刀切导致业务崩坏"。把整张用户表都加密,订单查询、对账、风控规则全都跑不动;把整张表都脱敏,运营分析、客服核实身份又失去了依据。安全手段如果和业务逻辑打架,最终一定是被业务绕开,防护形同虚设。
第二类问题叫"该护的没护住"。运维同学能通过数据库客户端直接看到明文手机号、身份证、银行卡,催生了最常见的内部数据泄露通道:有权限的人把数据导出到本地。统计口径不同,但行业里反复出现的结论是——相当比例的泄露来自内部人员或外包人员,而不是外部攻击者。
这两类问题的共同根因,是缺少一条主线:数据本身是有级别的,防护动作必须跟着级别走。分类分级不是合规报表里的那个表格,而是一套能被系统自动消费的数据属性。
一句话总结:先做分类分级,再做策略映射,最后才谈加密与脱敏。顺序反了,安全成本和业务阻力都会失控。
二、数据分类分级标签体系设计
分类分级建议拆成"分类"和"分级"两个维度,避免混在一起。
分类回答"这是什么数据",通常按业务域划分,例如:身份类、联系方式类、财产类、健康类、行为类、系统类。分类决定要不要用敏感规则去扫描它。
分级回答"有多重要、泄露后果多严重",给出统一的风险标尺。推荐四级模型,从低到高依次是:
| 级别 | 名称 | 典型字段举例 | 泄露后果 | 默认处置 |
|---|---|---|---|---|
| L1 | 公开 | 商品名称、公告标题、统计聚合值 | 几乎无影响 | 明文展示 |
| L2 | 内部 | 内部工单号、部门编号、非精确日志 | 有限影响,可用于社工铺垫 | 内部可见,对外脱敏 |
| L3 | 敏感 | 手机号、邮箱、住址、订单明细 | 可定位到个人,引发骚扰或诈骗 | 动态脱敏,按权限出明文/掩码 |
| L4 | 核心 | 身份证号、银行卡号、密码凭证、生物特征 | 直接用于盗用或欺诈 | 字段级加密存储,极少明文 |
| 未定级 | 待评估 | 新上线的未知字段 | 风险未知 | 按最严策略兜底或阻断 |
几个设计要点:
- 级别只增不减。字段一旦被定到 L3,不能随意降到 L2,降级需要审批留痕。
- 标签要可继承。一张表的字段如果没有显式打标,应按表级分类默认继承,减少人工成本。
- 标签要可被程序读取。打在元数据里,而不是写在文档里,网关、扫描器、审计系统都能直接引用。
- 兜底策略必须存在。未知字段默认走最严策略,避免"漏标即裸奔"。
- 标签要有生命周期。字段被删除、合并、语义变更时,标签应随之清理或重新评估,避免残留标签误导策略引擎。建议把标签变更纳入数据字典的版本管理,谁改了标签、为什么改、改成了什么,都留有记录。
- 标签粒度要适中。过粗会丢失防护精度,过细会带来惊人的维护量。经验上以"业务可理解的字段语义"为粒度最合适,既能被自动发现命中,又能被数据 owner 快速确认。
三、敏感数据自动发现与打标
人工逐字段定级在几百张表的规模下就难以为继,必须靠自动发现。自动发现的核心是"规则 + 抽样校验"的组合。
常见的识别依据有四类:
- 列名语义匹配。字段名命中
id_card、phone、mobile、email、bank、password、addr等字典。 - 数据内容特征。对抽样数据跑正则,例如手机号十一位、身份证十八位带校验位、邮箱含
@、银行卡十六到十九位。 - 外部知识库。参考行业标准字段目录或历史已定级字段,做相似度匹配。
- 业务语义标注。由研发在表注释或数据字典里声明字段敏感属性,作为高优先级信号。
下面是一段脱敏策略扫描的伪代码示例,展示如何把发现结果落为标签:
# 敏感字段扫描器:把命中规则的结果写成标签,而不是立即加密importre RULES={"id_card":re.compile(r"^\d{17}[\dXx]$"),"phone":re.compile(r"^1[3-9]\d{9}$"),"email":re.compile(r"^[^@\s]+@[^@\s]+\.[^@\s]+$"),"bank":re.compile(r"^\d{16,19}$"),}defscan_sample(rows):"""rows: 抽样得到的字段值列表,返回命中级别与依据"""labels={}forcol,valuesinrows.items():forvalinvalues:forname,patinRULES.items():ifpat.match(str(val)):labels[col]=("L3",name)break# 命中身份证或银行卡,直接升到核心级ifcolinlabelsandlabels[col][1]in("id_card","bank"):labels[col]=("L4",labels[col][1])returnlabels# 输出示例:{'phone':'L3', 'id_card':'L4', 'bank':'L4'}自动发现不是终点,而是起点。建议把扫描结果先进入"待确认"队列,由数据 owner 在两周内确认或修正,确认后的标签才正式生效。这样既能减轻人力,又能避免误标导致业务误伤。
四、定级到脱敏策略的自动映射
标签只有被策略消费才有意义。把级别映射到具体的脱敏与加密动作,是整套机制的中枢。下面给出一张可直接落地的策略映射表。
| 级别 | 存储形态 | 输出形态(按权限) | 脱敏函数 | 适用动作 |
|---|---|---|---|---|
| L1 公开 | 明文 | 明文 | 无 | 直接返回 |
| L2 内部 | 明文 | 内部明文 / 外部掩码 | 掩码 | 跨域访问时脱敏 |
| L3 敏感 | 明文或加密 | 权限决定明文/脱敏 | 掩码、部分遮蔽、替换 | 动态脱敏为主 |
| L4 核心 | 字段级加密 | 极少数高权限明文,其余脱敏或密文 | 保留格式加密、全遮蔽 | 加密存储 + 按需解密 |
| 未定级 | 按最严 | 按最严 | 全遮蔽或阻断 | 兜底拦截 |
映射时要区分两种脱敏逻辑:
- 静态脱敏:在数据出库、导出、同步到测试库时一次性处理,生成不可逆的脱敏副本。适合给开发、测试、分析用。
- 动态脱敏:在查询返回时按请求者身份实时决定展示形态,原始数据不动。适合生产环境客服、运营、运维的按需查看。
动态脱敏的关键在于"同一条 SQL,不同人看到不同结果",这要求网关能识别会话身份,并对照字段标签做实时改写。
以安当DBG为例,它在应用与数据库之间做透明代理,字段上携带的级别标签会在查询返回路径上被读取,再结合当前会话的权限角色,决定该字段返回明文、掩码还是密文。也就是说,定级结果不是给人看的报表,而是被网关直接执行的指令,应用层完全无感知,也就不需要为脱敏逻辑改一行业务代码。
五、权限三视图:明文、脱敏、密文
把"谁能看到什么"抽象成三种视图,是控制内部泄露最有效的方式:
- 明文视图:仅限数据 owner、经过审批的工单场景、以及必要的核验环节。例如客服核实身份时可看到完整手机号,但操作被录屏与审计。
- 脱敏视图:绝大多数日常查询的默认形态。手机号展示为
138****8000,身份证展示为310***********1234,既满足业务核对需要,又不暴露完整敏感值。 - 密文视图:运维人员通过数据库客户端直连时,核心字段直接返回密文。运维能看到"有数据、结构正常",但拿不到能用的明文,从根上切断"有权限就能拖库"的通道。
三视图不是靠应用硬编码,而是靠策略引擎在网关处统一裁定。好处是策略集中、可审计、可一键调整。今天发现某个角色越权,直接改映射规则即可,不依赖发版。
下面是一段策略判定的简化逻辑,说明三视图如何被实时裁定:
defresolve_view(level,role,purpose):# level: 字段级别;role: 请求者角色;purpose: 用途标签iflevelin("L1",):return"plain"# 公开数据,任何人明文iflevel=="L4"androle!="data_owner":return"cipher"# 非数据主人看核心字段,给密文iflevel=="L3"androlein("dev","ops"):return"mask"# 研发运维看敏感字段,给脱敏ifpurpose=="verify"androlein("csr","audit"):return"plain"# 核验用途且经审批,给明文return"mask"# 默认脱敏,兜底注意最后一行:任何未命中明确规则的请求,默认落到脱敏。这就是"默认安全"原则在数据库访问层的体现。
六、与字段级加密的边界划分
分类分级之后,团队常问一个问题:到底该脱敏还是该加密?两者职责不同,不能互相替代。
动态脱敏解决的是"展示层"的问题:数据以明文存在数据库中,但在返回给不当角色时被遮蔽。它的优势是对业务几乎零侵入、查询性能好、不影响范围检索;劣势是数据库落盘仍是明文,一旦存储层被攻破或备份泄露,数据就暴露了。
字段级加密解决的是"存储层"的问题:数据写入数据库前就被加密,落盘即密文。即使拿到数据库文件、备份或磁盘快照,没有密钥也解不开。它的优势是存储侧强防护;代价是密文不再能直接做范围查询、排序,除非采用保留格式加密这类特殊算法。
保留格式加密(FPE)是一个关键折中:加密后数据长度与字符集不变,因此LIKE前缀匹配、相等比较、部分范围判断仍可执行,只是无法做大小比较类的范围扫描。对于身份证、卡号这类需要按前缀检索又必须加密的字段,FPE 是优选。
需要强调的是,FPE 不是万能的。由于密文与明文格式一致,它牺牲了部分密文不可辨识性来换取可检索性,因此不能单独依赖 FPE 对抗"密文统计分析"类攻击,仍要结合密钥分权、访问审计一起使用。在工程落地时,通常只对确实需要检索的核心字段启用 FPE,其余核心字段使用更强但不可检索的加密算法,做到风险与可用性兼顾。
推荐的双层结构:
- 第一层用透明数据加密保护数据库文件、备份、表空间,抵御存储介质层面的泄露。
- 第二层用字段级加密网关针对 L4 核心字段做列级加密,密钥由独立的密钥管理系统托管,权限与数据库账号解耦。
两者配合,既挡住"拿到磁盘"的攻击,又挡住"拿到数据库账号"的内部泄露。脱敏则覆盖 L2、L3 在查询展示时的按需遮蔽,形成"存储加密 + 展示脱敏 + 权限三视图"的完整闭环。
七、定级与脱敏联动的架构设计
把前面几节串起来,一个可落地的联动架构大致长这样:
┌────────────┐ SQL ┌──────────────────────────┐ SQL ┌──────────┐ │ 应用系统 │ ─────────▶ │ 数据库加密网关(代理层) │ ─────────▶ │ 数据库 │ └────────────┘ │ │ └──────────┘ │ 1. 解析 SQL 与访问身份 │ │ 2. 读取字段分级标签 │ │ 3. 匹配脱敏/加密策略 │ │ 4. 改写结果:明/脱/密 │ └──────────────────────────┘ │ │ ┌───────────────────┘ └───────────────────┐ ▼ ▼ ┌───────────────┐ ┌───────────────┐ │ 分类分级中心 │◀── 自动发现打标 / 人工确认 ──────│ 密钥管理系统 │ │ (标签元数据存储)│ │ (密钥托管轮换) │ └───────────────┘ └───────────────┘ │ ▼ ┌───────────────┐ │ 全量审计日志 │◀── 谁、何时、查了什么、看到明/脱/密 └───────────────┘数据流说明:
- 应用照常发 SQL,不感知网关存在,实现应用零改造加密。
- 网关拦截所有进出流量,先识别"这是谁、在查什么字段"。
- 对照分类分级中心里的标签,把级别映射为对应的展示形态。
- L4 字段在写入时由网关完成字段级加密,密钥从密钥管理系统获取,数据库侧只存密文。
- 运维直连数据库时,由于字段已是密文且网关对客户端返回也按策略遮蔽,看到的是密文或脱敏值。
- 每一次访问都进入全量审计,记录主体、客体、动作、结果形态,事后可回溯。
这种架构的价值不在于某个单点技术多强,而在于把"分级—映射—执行—审计"串成一条自动化链路。安全策略从文档变成代码,从人治变成机制。
八、落地实施的五个阶段
把上述设计落到生产,建议分五个阶段推进,避免一次性大爆炸式改造:
- 盘点与打标阶段:用自动发现扫描全库字段,生成初始标签,进入待确认队列由数据 owner 复核。此阶段不动生产数据。
- 影子运行阶段:网关以只读旁路或镜像方式运行,记录"如果不干预会做什么",验证策略映射是否误伤业务,修正标签与规则。
- L4 先行阶段:先对核心级字段开启字段级加密,因为这部分风险最高、影响面相对可控,且通常需要配合密钥管理系统上线。
- 三视图阶段:对 L2、L3 开启动态脱敏与权限三视图,把运维、研发、客服的访问形态按角色分开。
- 持续运营阶段:新上线字段自动进入待定级队列,标签随业务变更评审更新,审计日志定期复盘异常访问。
每个阶段都要有可量化的验收指标,例如:核心字段加密覆盖率、敏感字段脱敏命中率、越权访问拦截数、审计覆盖率。没有度量的安全项目,很难向管理层证明价值,也容易在业务压力下被悄悄弱化。
九、常见误区与规避
误区一:把脱敏当成加密的替代品。脱敏不改变存储,只改变展示;一旦存储泄露,脱敏毫无作用。两者必须分层部署。
误区二:标签只打一次。业务字段会随版本演进新增、变更语义,标签需要纳入数据变更的评审流程,否则会出现"新字段漏标"。
误区三:权限过宽。给运维账号开了明文视图,等于把核心数据重新暴露。三视图的明文部分必须配合工单审批和录屏审计,而不是永久授权。
误区四:忽略性能。加解密与脱敏改写都会带来开销,需要通过保留格式加密、批量处理、连接池复用等手段把损耗压到可接受区间。实测中合理的工程实现能把单网关损耗控制在百分之五到十,并支撑数万量级的每秒查询。
误区五:审计日志不被查看。审计的价值在于可被检索和告警,而不是存满磁盘。应建立异常访问的实时告警,例如同一账号短时间大批量拉取敏感字段。
误区六:把分类分级当作一次性项目。数据在持续变化,新业务线、新表、新字段不断产生,定级工作若不能常态化,半年后标签就会严重失准。正确做法是把发现与打标做成周期性任务,并与数据上线流程挂钩,让分级成为数据治理的常态环节,而非应付检查的临时动作。
误区七:只防外部不防内部。不少团队把全部预算压在边界防火墙与入侵检测上,却放任内部运维、研发、外包人员以明文方式接触核心数据。事实上内部人员因权限天然拥有数据通道,一旦缺乏脱敏与三视图约束,就成为最便捷的泄露路径。数据库防泄露必须把内部访问纳入同等强度的管控。
方案参考
对于准备建设数据库防泄露能力的团队,给出几条通用落地建议,不涉及具体产品能力宣介:
选型要点
- 优先评估应用零改造方案。要求业务改代码的加密方案,落地成本与后续维护成本都会被严重低估,应尽可能选择对应用透明的代理或驱动层方案。
- 确认数据库矩阵覆盖度。生产环境往往是多类型数据库并存,选型时要核对是否支持团队实际使用的全部类型,包括主流开源库与国产数据库。
- 关注对检索友好性。若业务需要对加密字段做查询,应确认是否提供保留格式加密等可检索加密能力,避免加密即废掉查询。
- 密钥管理要独立。加密强度最终取决于密钥是否独立托管、是否支持轮换与分权,密钥与数据同库是最危险的架构。
实施建议
- 先分级后加密,先核心后全部。从风险最高、范围最清晰的 L4 核心字段切入,快速拿到防护收益,再逐步覆盖 L3、L2。
- 用影子运行降低风险。正式拦截前先旁路观察策略命中情况,用真实流量校验标签与映射,避免误伤业务。
- 把分类分级纳入数据变更流程。新表新字段上线即触发定级任务,防止出现防护盲区。
- 脱敏与加密分层部署。存储层用字段级加密挡泄露,展示层用动态脱敏控访问,二者互补而非替代。
风险规避
- 明文视图必须配审批与审计。任何能看明文的高权限通道,都要有工单、录屏、日志三重约束,否则等于打开后门。
- 性能损耗需压测。上线前用真实混合负载压测网关吞吐与延迟,确认损耗在业务可接受范围,预留扩容余量。
- 远程接入场景重点防护。当数据库允许远程访问或通过跳板机接入时,应把运维通道纳入网关统一拦截,避免绕过代理直连数据库。
- 兜底策略不可缺失。未知字段、未定级字段默认按最严策略处理,宁可先拦后放,不可先放后补。
- 审计要可被消费。日志不仅要能存,还要能检索、能告警、能复盘,让异常访问可被及时发现。
- 组织配套要同步。技术手段再完备,若缺少数据 owner 的定责机制与跨团队协同流程,分级标签仍会失真。治理先行,工具随后,才能把防护真正固化下来。