第1章 FPE与Tokenization的起源与应用场景

我在刚接触数据脱敏那几年,市面上主流方案要么是直接把数据库加密了,要么就是哈希加盐。但每次把加密后的字段贴到旧系统里,都会出问题——字段长度变了、格式乱了、索引失效……说白了就是“一加密就崩”。后来我才发现,业内早就有人在用两种更聪明的办法:格式保持加密(FPE)和Tokenization。这节课咱们就先聊聊它们是怎么来的,用在哪,以及为什么值得你花时间学。

1.1 为什么需要它们?数据泄露的痛点和合规要求

先看一张图,我尽量把它们的定位说清楚:

FPE 与 Tokenization 的起源与应用场景 FPE:格式保持加密 起源:2000年代,信用卡号保护需求 标准化:NIST SP 800-38G (FF1, FF3) 特点:可逆、保留格式、密钥管理 Tokenization:令牌化 起源:2005年,PCI DSS合规推动 成熟:支付行业服务商兴起 特点:替换为、映射表、无密码 本质区别:FPE用算法加密,用映射表 典型应用场景 FPE:数据库字段加密、遗留系统兼容、日志脱敏 Tokenization:支付卡号保护、云数据安全、数据共享场景

为什么会有这两个东西?我举个例子。十多年前我做电商平台,业务要求把信用卡号存在数据库里,但明文存肯定违规。我试过AES加密,一加密字段变成16字节,原来的16位卡号没法用,业务方直接炸毛。那时候我才理解——很多老系统根本接受不了格式变化。于是FPE和Tokenization开始被重视。

1.2 FPE的起源与核心思想

FPE(Format-Preserving Encryption)最早来自密码学家的一个小想法:能不能在加密时让输出跟输入长得一样?比如输入16位信用卡号,加密后也输出16位数字。这样数据库表结构不用改,索引不用重建,历史查询也能通。

我记得最初看到NIST在2016年发布了SP 800-38G标准,里面定义了FF1和FF3两种算法。说白了,就是把一段明文切分成字符集,然后在有限域上做Feistel网络迭代。这样做的好处是密文保持了原始格式,坏处是算法实现稍微复杂点,而且密钥泄漏就全完了。我之前在一个金融项目里用过FF1,踩过一个坑——FF1要求明文长度至少2,如果只加密1个字符就会报错。所以你要么补位,要么改用FF3。

小提示:FPE的典型算法是FF1和FF3。FF1支持更灵活的字符集(数字、字母、混合),FF3性能略好但对长度有限制(至少2)。实际选型建议先确认你需要的字段最小长度。

1.3 Tokenization的起源与核心思想

Tokenization跟FPE完全不是一个路子。它不加密,而是替换。用一个无意义的令牌()代替原始敏感数据,令牌和原文的映射关系存在一个安全的库里。说白了,就是把“真钱”换成“游戏币”,你拿游戏币去玩,别人永远不知道你兜里有多少真钱。

Tokenization最早在支付行业普及,因为PCI DSS标准要求存储的卡号必须“不可读”。但很多公司又想保留卡号后四位做校验,于是一套完整的服务就起来了。我记得2017年帮一家金融服务公司做数据脱敏,他们用了Tokenization之后,监管来审计,直接拿出库的访问日志就过关了,效率很高。但要注意,Tokenization本身不具备加密强度,它依赖库的安全和访问控制。如果你的库被攻破,映射关系就全泄露了。

注意:Tokenization ≠ 加密。它只是一个替换机制,安全性完全取决于映射表的保护措施。如果映射表被盗,等于所有全部还原。所以生产环境通常需要独立的HSM或硬件安全模块来管理库。

1.4 适用场景对比表

特性FPETokenization
保留格式是(加密后格式完全一致)是(可以生成指定格式的)
可逆性可逆(用密钥解密)可逆(查映射表)
存储影响仅需密钥,无需额外存储需要存储映射表,空间随数据量线性增长
安全性依赖密码算法强度 + 密钥管理映射表访问控制 + 网络隔离
性能计算密集型(加解密较慢)查询密集型(映射表查找较快)
典型场景数据库字段加密、日志脱敏、兼容旧系统支付数据保护、云原生数据脱敏、数据共享

你看这个表格,两边各有千秋。但有一点我说实话:很多人觉得Tokenization更简单,因为不用写加解密代码,调个API就行。但你想想看,一旦数据量上去,库的维护成本非常高。我见过一个案例,每天新增几亿条,半年后查询性能直接雪崩。而FPE虽然计算慢一点,但密钥管理成熟后,存储成本几乎为零。

1.5 我的个人经验与避坑提示

  • 先确认字段格式是否稳定。假如字段里允许带空格或特殊符号,FPE的字符集定义就要仔细。我曾在某个项目中用FPE加密邮箱地址,结果域名部分因为大小写被业务方投诉……后来不得不加一个case-folding预处理。
  • Tokenization不适合超大映射表。如果库无法全部放入内存,每次查询都读磁盘,延迟就会飙升。我记得有一次优化,把按范围分片到多个Redis集群,才算搞定。
  • 两者可以一起用。比如:对身份证号用FPE加密,同时生成一个用于外部共享,这样解密权限只留给内部系统,而外部只有单向的。
  • 我曾经踩过一个坑:在切换到生产环境前,忘记测试FPE加密后是否还能做字符串比较。因为FPE输出虽然格式一致,但密文本身改变了,如果有依赖原始值做排序、分组、join的查询,需要提前改SQL。
核心一句话:如果你需要保留字段的格式、可逆性、且不想引入额外存储,选FPE;如果你的业务天然存在服务(比如支付平台),或者你有强隔离的库基础设施,选Tokenization。两者不是替代关系,而是各管一摊。