FPE 简介与 FF3 概述

大家好,我是你们这堂课的主讲。先聊个实在的:格式保留加密(FPE)到底解决了什么问题?

你想想看,传统的 AES、DES 加密一个 16 位信用卡号,出来的是一串乱码——可能 32 位,还有特殊字符。数据库里原来存 varchar(16) 的字段,突然装不下了。系统要改字段长度、改校验逻辑、改接口,甚至索引都得重建。这事我经历过,一次核心账务系统改造,光改字段长度就折腾了两周。

FPE 的核心就一句话:加密后的密文和明文格式一致。16 位数字进去,还是 16 位数字出来。系统不用改任何数据结构,直接替换密文就行。

FPE 是怎么做到的?

说白了,FPE 不是简单的“加密再截断”。它在加密过程中就控制了输出的字符集和长度。比如基数为 10(数字 0-9),长度固定为 16,那么密文空间就是 10¹⁶ 种可能——和明文空间完全一致。加密算法在这个空间内做双射置换。

关键概念
格式保留加密 = 在固定格式空间内的双射置换。输入是什么格式,输出就是什么格式。

我在项目中遇到过一个坑:有人用 AES 加密后再 base64 缩短,以为就是“格式保留”了。结果不是。base64 后的字符集包含了 '+' 和 '/',数据库字段要求纯数字,直接报错。所以,纯数字、纯字母、字母数字混合,FPE 都能处理,但每种场景的基数和长度必须精确匹配。

传统加密 vs 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 网络:

  1. 输入:明文(格式字符串)、密钥、调整参数(tweak)、基数(radix,如 10 表示数字)。
  2. 把明文分成左右两半,比如把 16 位数字拆成前 8 位和后 8 位。
  3. 每一轮用 AES 加密一部分,再结合 tweak 和轮数,产生一个随机数。
  4. 用这个随机数“置换”另一部分的数据,并交换左右。
  5. 重复 8 轮(FF3-1 是 8 轮,旧版 FF3 是 8 轮但有漏洞)。
  6. 最终输出密文,和明文同长度、同字符集。

为什么会这样设计?因为要保证 1:1 映射——每个明文对应唯一密文,且可逆。Feistel 网络天然保证了这一点,不管里面的函数多复杂,解密时反向走一遍就行。

我最初学的时候觉得 Feistel 很绕,后来参与了一个 FF3 的开源实现,边写代码边理解,一下子就通了。所以别怕,后面章节我们会手写一个简化版。

FPE 与 FF3 知识体系 格式保留加密 (FPE) 传统加密破坏格式 字段改造、索引失效 FF3-1 (NIST SP 800-38G) Feistel 网络 + AES 应用场景 金融 · 医疗 · 政府 · 通信 · 自定义编码 核心机制:Feistel 网络 + 调整参数 密钥 + tweak 双射置换

这张图把本章的逻辑串起来了:FPE 解决传统加密的格式破坏问题;FF3-1 是当前最实用的标准;它用 Feistel 网络配合调整参数实现加密;应用场景遍布金融、医疗等敏感数据领域。后面我们会一步步深入每个环节。

本章小结
· FPE = 加密后格式不变,避免了系统改造。
· FF3-1 是目前 NIST 推荐的 FPE 模式,基于 Feistel 网络。
· 实际使用中必须注意旧版 FF3 的安全漏洞。
· 应用场景多,但前提是明文格式固定。

嗯,第一课先到这里。下次我会带你一步步写一个 FF3 的加密函数,到时你就知道那些数学概念具体怎么落地了。