第2章 格式保留加密的核心思想

说实话,刚接触FPE时我也觉得它挺绕的——加密就加密,为什么还要“保留格式”?但等你真正把一个16位的信用卡号塞进AES,出来一串乱七八糟的二进制,再回头看看业务方的表情……你就懂了。格式保留加密,说白了就是:加密后的密文长得和明文一模一样——数字还是数字,字母还是字母,长度不变、字符集不变。这不是花哨,这是生产环境的硬需求。

2.1 为什么要死磕“格式不变”?

我参与过一个银行测试数据脱敏项目。生产库里有几千万条银行卡号,需要加密后放到测试环境。一开始用的标准AES,结果加密完的字段变成64位十六进制串,数据库字段装不下,应用端直接报错。业务方追着我喊:“这玩意儿我连导入都导不进去!”

你想想看,如果加密后的数据格式变了,那系统就要改表结构、改校验逻辑、改接口协议——成本翻倍,还容易出bug。FPE的核心价值就是:加密前后,数据的类型、长度、校验规则完全一致。可以直接替换原字段,应用层零改动。

举个最常用的场景:

  • 信用卡号:16位数字,包含Luhn校验位。FPE加密后仍是16位数字,且校验位依然合法。
  • 身份证号:18位,数字+字母X。加密后保持18位,字符集不变。
  • 电话号码:11位数字。加密后还是11位数字。

嗯,这里要注意一个陷阱:格式保留 ≠ 长度不变。比如对于包含字母和数字的字段,FPE可以只保留字母部分大小写?不是的,FPE的“格式”是指整个明文字符集和长度都固定,不是你想保留哪部分就保留哪部分。我一同事在项目中试图只保留数字部分而改变字母部分——结果解密的时候彻底乱套。

2.2 和标准加密硬碰硬:一张表说清楚

为什么不能用AES直接干?咱们直接对比看看:

对比维度 标准加密(如AES) 格式保留加密(FPE)
输出长度 通常是固定块大小(16/32字节) 与输入长度严格相等
输出字符集 二进制或十六进制串 与输入字符集一致(数字、字母等)
数据类型适应性 只能处理二进制块 可适配任意有限字符集(数字、字母、ASCII)
应用改造代价 需要修改字段定义、接口、校验逻辑 直接替换,零改动
典型场景 文件加密、通信加密 数据库字段脱敏、令牌化、格式敏感数据保护

我刚开始学习FPE时,老纠结一个问题:既然AES这么安全,为什么不能加密完再把二进制转成数字?但转念一想——你怎么保证转换后的数字长度刚好是16位?而且每次转换可能引入概率冲突,解密时还得逆向映射回来,这本质上就是FPE要做的事情,只不过FPE给出了一个数学上可证明的、一步到位的解法。

2.3 FPE的三大支柱:格式、可逆、安全

做工程的人最怕“三缺一”。FPE要落地,三个条件必须同时满足:

三大要素:
1. 格式保留 —— 密文与明文同长度、同字符集、同结构。
2. 可逆性 —— 解密可以完整还原出原始明文。
3. 安全性 —— 达到与底层分组密码(如AES)等效的安全强度。

格式:这是FPE的安身立命之本。没有格式保留,那跟AES就没区别了。具体实现时,FPE算法(比如FF3)会先把明文映射到数字域(比如把字母串编码为0~25的整数序列),然后在数字域上做一个保持区间长度不变的置换,再映射回字符。这个映射过程必须是一一对应的,否则解密时无法还原。

可逆:听起来是废话,但我在实际调FF3时踩过一个坑——密钥和tweak必须严格一致。在项目里,有人把tweak记错了,加密时用"ABC",解密时用"abc",结果解密出来的数据全是乱的。所以可逆不仅算法要可逆,参数管理也必须确保一致性。

安全:FPE的安全性通常建立在底层分组密码(如AES)的安全之上。FF3模式本身被证明是安全PRP(伪随机置换),但要注意,FPE的安全性不能超过其底层密码。当初FF1/FF2曾被发现有边界攻击,需要额外防护。而FF3-1是目前NIST推荐的标准,相对成熟。

工程提示:FF3对短数据(比如小于2个字符)的支持不太好,官方规定最小明文长度是2(数字域)或1(某些字符集)。如果你的字段短到只有一个字符,考虑填充或改用FF1。我曾在工单系统里碰到一个“单字符状态码”字段,用FF3直接报参数错误,后来换成了FF1才搞定。
避坑指南:千万不要自己发明“格式保留”算法——比如对AES输出做base64再截断。这种土办法会破坏可逆性和安全性。我曾经见过一个团队把AES密文转为十六进制后再取前N位,结果解密时因为截断丢失信息,数据永远无法还原。FPE必须是数学上完整的算法。

知识结构图:FPE核心思想与对比

下面这张图帮你把这一章的主要逻辑串起来。左边是标准加密的困境,右边是FPE的解决方案,中间是三大要素形成支撑。

格式保留加密 vs 标准加密:核心逻辑 明文(数字16位) AES加密 密文:64位十六进制 格式不匹配!字段溢出 ✘ 明文(数字16位) FF3加密 密文:16位数字 格式完整保留 ✓ ✔ 格式保留 可逆性 安全性 格式 可逆 安全 三大要素缺一不可

看明白了吧?左边那种加密产物,系统根本没法直接存。右边FPE出来的东西,你直接往数据库旧字段里塞,旧代码完全不用改。而底下那三个要素——格式、可逆、安全——就是支撑FPE这个桥梁的三根柱子。少一根,桥就塌了。

这一章我们把FPE的核心思想讲透了:格式保留是出发点,可逆性是底线,安全性是保障。后面几章我们会钻进FF3的算法细节里,看看那套“数字域置换”到底是怎么做到的。但在这之前,我强烈建议你动手跑一下FF3的示例代码,哪怕只是加密一个"1234567890123456",看看输出是不是真的也是16位数字——亲眼看到比什么都管用。