FPE 简介与 FF3 概述
大家好,我是你们这堂课的主讲。先聊个实在的:格式保留加密(FPE)到底解决了什么问题?
你想想看,传统的 AES、DES 加密一个 16 位信用卡号,出来的是一串乱码——可能 32 位,还有特殊字符。数据库里原来存 varchar(16) 的字段,突然装不下了。系统要改字段长度、改校验逻辑、改接口,甚至索引都得重建。这事我经历过,一次核心账务系统改造,光改字段长度就折腾了两周。
FPE 的核心就一句话:加密后的密文和明文格式一致。16 位数字进去,还是 16 位数字出来。系统不用改任何数据结构,直接替换密文就行。
FPE 是怎么做到的?
说白了,FPE 不是简单的“加密再截断”。它在加密过程中就控制了输出的字符集和长度。比如基数为 10(数字 0-9),长度固定为 16,那么密文空间就是 10¹⁶ 种可能——和明文空间完全一致。加密算法在这个空间内做双射置换。
格式保留加密 = 在固定格式空间内的双射置换。输入是什么格式,输出就是什么格式。
我在项目中遇到过一个坑:有人用 AES 加密后再 base64 缩短,以为就是“格式保留”了。结果不是。base64 后的字符集包含了 '+' 和 '/',数据库字段要求纯数字,直接报错。所以,纯数字、纯字母、字母数字混合,FPE 都能处理,但每种场景的基数和长度必须精确匹配。
| 维度 | 传统加密(AES/CBC) | FPE(FF3) |
|---|---|---|
| 输出格式 | 任意二进制,长度不定 | 与输入完全一致(数字、字母等) |
| 字段改造 | 需要改类型、长度、索引 | 零改造,直接替换 |
| 密钥管理 | 标准对称密钥 | 标准对称密钥 + 调整参数(tweak) |
| 安全性 | 标准安全(IND-CPA) | 同样达到 IND-CPA,但受限于格式空间 |
FF3 的诞生背景
2016 年 NIST 发布了 SP 800-38G 标准,里面包含两种 FPE 模式:FF1 和 FF3。FF3 是后来的版本,更高效——它的 Feistel 网络轮数更少,而且支持更短的输入长度。不过,2017 年有人发现了 FF3 的一个理论漏洞:当明文长度很短时,攻击者可以通过 slide attack 降低安全强度。所以很快 NIST 推出了 FF3-1,主要改了轮数和调整参数的处理方式。
我曾经在一个金融项目中看到同事直接用了开源的 FF3 实现(2017 年之前的版本),没有升级到 FF3-1。幸好我们做安全审计时发现,立刻替换了。现在生产环境必须用 FF3-1,否则合规不过。切记:不要直接用旧版 FF3。
为什么名字叫“FF3”?其实很简单:FF 是 Feistel-based Format-preserving encryption 的缩写,数字 3 代表该模式的第三版设计思路。你只要知道它基于 Feistel 网络就好了。
应用场景概览
FPE 在实际中用得最多的就是这几类:
- 金融:信用卡 PAN(主账号)、CVV、银行卡号。国内很多支付系统做脱敏时就用的 FPE。
- 医疗:社保号、病历号、保险号。患者数据合规要求加密,但医院系统不想改字段。
- 政府:身份证号、护照号、驾照号。你在某省政务云项目中就能见到。
- 通信:电话号码、部分邮箱前缀。注意邮箱整体无法保留格式(因为长度和字符集太复杂),但用户名部分可以。
- 其他:自定义编码(如订单号、设备序列号)。只要你能确定字符集和长度,FPE 就能上。
选场景时,我一般先问三个问题:① 明文格式是否固定?② 是否必须保持查询索引?③ 合规要求是否需要可逆加密?如果三个都是“是”,FPE 几乎是不二之选。
FF3 的核心原理(先有个印象)
这里先不深入数学细节,只讲高层逻辑。FF3 像是一个定制的 Feistel 网络:
- 输入:明文(格式字符串)、密钥、调整参数(tweak)、基数(radix,如 10 表示数字)。
- 把明文分成左右两半,比如把 16 位数字拆成前 8 位和后 8 位。
- 每一轮用 AES 加密一部分,再结合 tweak 和轮数,产生一个随机数。
- 用这个随机数“置换”另一部分的数据,并交换左右。
- 重复 8 轮(FF3-1 是 8 轮,旧版 FF3 是 8 轮但有漏洞)。
- 最终输出密文,和明文同长度、同字符集。
为什么会这样设计?因为要保证 1:1 映射——每个明文对应唯一密文,且可逆。Feistel 网络天然保证了这一点,不管里面的函数多复杂,解密时反向走一遍就行。
我最初学的时候觉得 Feistel 很绕,后来参与了一个 FF3 的开源实现,边写代码边理解,一下子就通了。所以别怕,后面章节我们会手写一个简化版。
这张图把本章的逻辑串起来了:FPE 解决传统加密的格式破坏问题;FF3-1 是当前最实用的标准;它用 Feistel 网络配合调整参数实现加密;应用场景遍布金融、医疗等敏感数据领域。后面我们会一步步深入每个环节。
· FPE = 加密后格式不变,避免了系统改造。
· FF3-1 是目前 NIST 推荐的 FPE 模式,基于 Feistel 网络。
· 实际使用中必须注意旧版 FF3 的安全漏洞。
· 应用场景多,但前提是明文格式固定。
嗯,第一课先到这里。下次我会带你一步步写一个 FF3 的加密函数,到时你就知道那些数学概念具体怎么落地了。