4、数据格式保留特性对比

数据格式保留,这词听着挺学院派。说白了就是:加密或脱敏之后,出来的东西长得还跟原来一个样。

我在银行做支付系统改造时碰到过真实场景——信用卡号脱敏后必须还是16位数字,前6位和后4位保持原样,中间用星号也行;但如果是加密,那密文也得是16位数字,不能变成长长一串乱码。数据库字段长度是定死的,一变就炸。

这一章我就跟你聊聊,Tokenization 和字段级加密在这件事上到底差多远。你想想看,如果选了错的技术,上线当天就被 DBA 追着骂……我经历过,所以这篇你值得认真看。

什么是格式保留?

格式保留(Format-Preserving)是指:密文或令牌的长度、字符集、校验位规则与明文保持一致。

  • 长度一致:明文 16 位,密文也得是 16 位。
  • 字符集一致:明文是数字,密文就不能冒出字母或特殊符号。
  • 业务语义保留:比如身份证号最后一位是校验码,脱敏后校验码逻辑还能走通?多数场景不需要保留校验,但长度和字符集是硬要求。

为什么这么重要?因为大多数遗留系统的数据库字段、API 契约、展示模板都是写死的。改长度意味着要改表结构、改接口、改 UI,成本极高。

Tokenization 的格式保留机制

Tokenization 天然擅长这件事。它的核心思路是:用一个同样格式的令牌去替换原始值。

实现方式主要有三种:

  1. 查表映射:随机生成符合格式的令牌,存放到映射表。读取时查表还原。格式完全可控。
  2. 基于 FF1 / FF3 的格式保留加密:用 NIST 标准算法(FF1 / FF3)对明文加密,输出与明文同格式的密文。这套算法我之前在信用卡号脱敏项目中用过,挺稳的。
  3. 伪随机生成 + 去重:用随机数生成器产出符合格式的令牌,配合唯一索引防止碰撞。适合高吞吐场景。

我记得有一次给某支付机构做令牌服务,要求令牌的前4位必须是发卡行识别码(BIN),后12位随机。我们用 FF1 加密时把 BIN 当 tweak 传进去,出来的令牌前4位始终是原 BIN,后12位是加密后的随机数字。测试下来,100 万条数据无碰撞,完美兼容已有风控规则。

要点:Tokenization 的格式保留是“设计目标”,不是“副作用”。映射表和 FF1/FF3 都能精确控制输出格式。

字段级加密的格式保留困境

字段级加密(列级加密、应用层加密等)通常使用标准分组加密算法,比如 AES-128-CBC、AES-256-GCM。这些算法输出的是二进制密文,长度会膨胀,字符集也是乱码。

你可以看看这个问题有多严重:

明文类型 明文长度 AES-128-CBC 密文长度 字符集变化
信用卡号(数字) 16 字节 32 字节(Base64 后 ~44 字符) 数字 → 字母+数字+符号
身份证号(数字+字母) 18 字节 32 字节(Base64 后 ~44 字符) 数字+大写字母 → 混合乱码
邮箱(ASCII) 平均 20 字节 32 字节(Base64 后 ~44 字符) 可读文本 → 不可读

看到了吧?密文比明文长一倍还多,而且变成了一堆没法看的乱码。数据库字段要是 varchar(16) 直接塞不进去,必须改字段长度,还得处理编码。

有人可能会说:「我用 AES 的 CTR 模式,密文长度等于明文长度。」——理论上是的,但 CTR 模式不做认证,安全等级不够。企业级应用至少用 GCM 或 CCM,GCM 会多出 12 字节的 IV 和 16 字节的 tag,最终还是要膨胀。

避坑:我曾经见过一个项目,团队选了 AES-GCM 加密信用卡号,上线后才发现数据库 varchar(16) 存不下密文,紧急改表结构,回滚加加班搞了三天。所以选型前一定要先确认字段长度限制。

Tokenization vs 字段级加密:格式保留能力对比

下面这张表总结了核心差异,我建议你直接截图存手机里,选型时翻出来看:

对比维度 Tokenization 字段级加密
格式保留能力 强:可精确控制长度、字符集、校验位 弱:密文长度膨胀、字符集不可控
对现有系统的侵入 低:无需改字段长度、无需改展示层 高:需扩字段长度、加 Base64 编解码
算法实现 FF1/FF3(标准)、映射表(自定义) AES-GCM / AES-CBC(通用)
典型场景 信用卡号、身份证号、手机号、邮箱 密码、密钥、敏感非结构化文本
安全等级 取决于令牌存储安全性、FF1/FF3 具备标准安全性 强:基于标准密码学,抗攻击能力强
性能开销 低:查表 O(1) 或 FF 加密快 中:分组加密 + 认证标签计算

实战技巧:如果业务要求保留格式但你又必须用字段级加密(例如合规要求使用国家密码管理局认证的算法),可以考虑在应用层做“后处理”——把 AES 密文截断或重新编码。但这么做会破坏密文完整性验证,不建议在金融、医疗等高安全场景使用。

核心流程:格式保留选型决策图

下面这张 SVG 图帮你捋清思路。红色分支表示密文膨胀会带来问题,绿色分支表示可以沿用现有数据结构。

格式保留选型决策流程 原始敏感数据 方案A: Tokenization FF1/FF3 或 查表映射 输出:格式完全保留 无需改数据库字段 长度/字符集/校验不变 方案B: 字段级加密 AES-GCM / AES-CBC 输出:密文膨胀 + 乱码 必须改字段长度类型 需Base64编码处理 结论:若格式保留是硬约束,选 Tokenization;否则可选字段级加密 红色分支表示高侵入性改造风险,绿色分支表示低成本兼容

实际选型建议

我个人的经验是:先问自己三个问题。

  1. 现有系统能不能改字段长度? —— 如果改不了,直接选 Tokenization。
  2. 业务是否要求可逆(需要还原原始值)? —— Tokenization 可以双向,而字段级加密天然可逆。但如果你只用来脱敏(不可逆),Tokenization 也支持单向哈希令牌。
  3. 合规有没有指定加密算法? —— 有些行业标准强制要求使用国家密码算法(SM4等)。这时字段级加密是必选项,那你就得硬着头皮改字段长度。

我的建议:如果条款允许,尽量选择 Tokenization。原因很简单——不改数据库、不改 API、不改前端。我亲眼见过一个上线前一周因为字段长度问题回滚的项目,项目经理头发都白了。

好了,格式保留这块的核心对比就到这。记住一句话:字段级加密是给数据安全部门看的,Tokenization 是给业务系统用的。选对了格式保留的方式,后面很多坑都能直接绕过去。