本章核心:格式保留令牌化(FPE)与非格式保留令牌化,是数据脱敏的两种典型路线。搞懂它们的差异,你才能在实际项目里选对路子。

4. 令牌化类型深度解析:FPE vs Non-FPE

说实话,很多人一上来就问我:“令牌化不就是把敏感数据换成一串随机数吗?” 我刚开始也这么想。直到我在银行项目里,遇到一个必须保持信用卡号格式的合规要求——原数据是16位数字,脱敏后还得是16位数字,不能出现字母。这时候我才明白,令牌化没那么简单。

咱们这次聊的两个类型,说白了就是:FPE(Format-Preserving Encryption) 和 Non-FPE(非格式保留令牌化)。一个要“长得像”,一个无所谓。怎么选?往下看。

4.1. 什么是格式保留令牌化(FPE)

FPE,全称 Format-Preserving Encryption。它的核心就是你输入“1234-5678-9012-3456”,输出还是4组4位数字,中间有分隔符,长度不变。我习惯叫它“整容不变脸”——数据变了,样子没变。

为什么需要它?举个例子:你有个老系统,数据库字段写死了“信用卡号必须是16位数字,带连字符”。你要是给它换成32位随机字符串,系统直接报错。FPE就是为解决这种兼容性问题诞生的。

避坑指南:我曾经在支付系统里吃过亏——直接用了标准AES做令牌化,结果下游的卡号校验模块全部崩溃。后来换成FPE,一行代码没改,就解决了。所以,记住:FPE不改变数据类型和格式。

FPE的典型算法

  • FF1(NIST SP 800-38G):基于Feistel网络,支持任意字母表(数字、字母、符号)。我最常用它处理身份证号、护照号。
  • FF3-1(NIST修订版):速度更快,但最小输入长度有限制(比如至少2个字符)。我一般在处理较短字段(如邮编)时用。
  • VAES3(Volt 套件):商业实现,适合高性能场景。我在高并发API网关里见过它的影子。

FPE的优缺点

维度 优点 缺点
兼容性 不改数据库Schema,零侵入 对格式有严格要求,无法处理长度变化
安全性 可逆(有密钥就能还原),适合合规审计 密钥泄露则全量暴露
性能 算法成熟,硬件加速友好 FF1/FF3-1在长字段上略慢于对称加密
适用场景 信用卡、手机号、身份证、社会安全号(SSN) 不适合格式不固定的文本(如邮件地址)

4.2. 什么是非格式保留令牌化(Non-FPE)

Non-FPE 就简单多了。你输入“abc@example.com”,输出可能是“tok_8f3a9b2c”。长度变了,格式变了,甚至加了前缀。说白了,它不关心“原数据长什么样”。

我个人习惯把 Non-FPE 用在数据湖、分析库、日志脱敏场景里。为什么?因为这些地方不需要保持格式,反而希望令牌尽可能短(节省存储),或者加一些元信息(比如前缀标识来源)。

Non-FPE的常见实现方式

  • 随机令牌生成:直接生成UUID或随机定长字符串,与原始数据做映射表。我最常用的方式,简单、安全。
  • 哈希+盐值:SHA-256 + 随机盐,截取前N位。注意:不可逆,适合静态脱敏。
  • AES-GCM-SIV + 截断:保留高级加密的可逆性,但输出是二进制,要Base64编码后再截断。我在日志脱敏项目里用过。

Non-FPE的优缺点

维度 优点 缺点
灵活性 长度、格式自由,可加前缀/后缀 无法兼容老系统的格式校验
安全性 映射表+密钥双重保护,可细粒度控制访问 映射表可能成为性能瓶颈
性能 生成速度快,适合大规模流式处理 高频查询时,映射表查找有延迟
适用场景 数据仓库、日志、API网关、用户ID脱敏 不适合支付卡号、IBAN等必须保留格式的字段
特别注意:不要以为 Non-FPE 就是“随便换”。你想想看,如果你把用户邮箱映射成“user_001”,攻击者通过观察多个令牌的规律,就能推断出用户的活跃度。所以,令牌必须是随机的、不可猜测的。我建议至少使用128位随机数。

4.3. 怎么选:FPE vs Non-FPE 对比总结

你可能会问:“那我到底用哪个?” 嗯,这里要注意。我的经验是:别纠结于“哪个更安全”,安全级别可以用密钥长度和算法强度达成一致。真正的分水岭是格式要求和系统兼容性。

下面这张表我每次做方案设计都贴在白板上,你直接拿去用。

判断条件 选 FPE 选 Non-FPE
下游系统是否校验格式? 是(例如:卡号校验、身份证校验) 否(纯存储、分析、日志)
是否需要保留原字段长度? 是 否
令牌是否需要可逆? 是(FPE天生可逆) 可逆/不可逆都行(映射表决定)
性能要求高吗? 中等(算法有计算开销) 高(简单随机生成,很快)
是否需要跨系统一致性? 是(同一密钥,同一算法,全局一致) 否(映射表各自独立)

我个人习惯这样定策略:

  1. 核心支付敏感字段(卡号、CVV、有效期)→ 必须用 FPE。因为PCI-DSS要求你“无法从格式上识别出信用卡”,但系统又要保持格式。
  2. 个人身份信息(姓名、邮箱、电话)→ 首选 Non-FPE。因为这些字段格式各异,保持原样没意义。我在用户画像项目里就是这么干的。
  3. 混合场景(既有结构字段又有非结构字段)→ 分开处理:结构化用FPE,非结构化用Non-FPE。记得用不同的密钥空间。

最后,说一个很多人容易犯的错。你想想看,如果FPE算法选错了参数(比如字母表定义不完整),可能会触发不可逆的错误。我曾经遇到一个案例:同事把字母表写成“0-9”,结果输入字段里有个字母,FPE直接报错。所以,用FPE前,必须精确理解你字段的合法字符集和长度边界。

令牌化类型选择流程 输入敏感数据 下游系统校验格式? 是 否 FPE(格式保留) Non-FPE(自由格式) 确定合法字符集与长度 选择FF1/FF3-1算法 生成随机令牌/UUID 维护映射表独立存储

总结一下:FPE 和 Non-FPE 没有好坏之分,只有合不合适。我自己的项目中,80% 的字段用的是 Non-FPE(因为大部分是内部分析和日志),只有 20% 的核心字段我会用 FPE。你根据你的业务预期,对号入座就行。