2. FPE基本原理:保形加密与保序加密的区别

聊FPE(保留格式加密),你首先得明白一件事——它不是为了“加密”而生的,而是为了解决一个很现实的问题:加密之后的数据格式变了,下游系统直接罢工。

我刚开始接触数据脱敏时,遇到一个典型场景:要对信用卡号做脱敏,但前端系统死活不认16位以外的数字。传统的AES加密会输出一堆乱码,根本没法用。后来我才发现,FPE内部其实分了两条技术路线——保形加密和保序加密。二者虽然都叫FPE,但解决的问题和设计思路截然不同。

2.1 保形加密(Format‑Preserving Encryption)

保形加密的目标很简单:密文和明文的格式完全相同。比如输入一个16位的信用卡号,输出还是一个16位的数字串;输入一个合法的电子邮件地址,输出仍然符合xxx@xxx.xxx的结构。至于大小顺序?完全不关心。

我记得在做一个支付系统的测试数据脱敏时,系统要求脱敏后的卡号必须通过Luhn算法校验。当时我试了好几个方案,最后用FF1算法(一种保形加密标准)实现了——密文看起来完全像真实卡号,连校验位都自动对齐。保形加密的核心原理是:把明文映射到同一个有限字符集上的一个伪随机排列。说白了,就是用Feistel网络或者循环分组,在保持字符集和长度不变的前提下,完成置换。

保形加密的特点

  • 输出格式与输入完全相同(长度、字符集、边界符)
  • 安全性依赖分组密码(如AES),具备可证明安全
  • 不可逆(单向函数),但支持解密恢复明文
  • 常用于敏感数据脱敏、格式严苛的遗留系统

2.2 保序加密(Order‑Preserving Encryption)

保序加密走的是另一条路。它的核心目标是:密文的大小关系与明文完全一致。如果明文A < 明文B,那么加密后的密文A < 密文B。至于输出格式是不是跟原来一样?不一定,很多时候密文就是一段二进制串,长度可能会变。

我曾在数据库加密项目中遇到过这种需求:业务需要直接在密文上做范围查询(比如查询年龄在20到30之间的记录)。如果用了保形加密,只能全表解密再过滤,性能直接崩溃。保序加密恰好解决了这个问题——它本质上是一个单调递增的映射函数。最简单的实现就是把明文按数值区间映射到密文空间,但安全级别很低。工业界常用的是基于线性分流或随机保序编码的方案,比如Boldyreva构造。

我曾经踩过的坑

有一次我图省事,直接用了简单的线性映射来做保序加密——把明文乘以一个固定系数再加一个偏移。看起来顺序保住了,但攻击者只要拿到几个明密文对,就能猜出密钥。后来我才发现,真正的保序加密必须引入随机化或噪声,同时保证单调性不破。而保形加密就没有这个纠结。选型时一定想清楚你到底要“保形”还是“保序”,这两个东西不能混为一谈。

2.3 两者的核心区别

对比维度 保形加密 保序加密
核心目的 保持输出格式与输入相同 保持输出数值顺序与输入相同
输出格式 固定长度、固定字符集 通常为二进制串,长度可变
顺序关系 不保持(密文无序) 严格保持(密文有序)
安全性 可证明安全(如FF1/FF3达到PRP安全) 语义安全较弱,一般只达到“选择明文攻击下的不可区分”
查询能力 只能精确匹配,不能直接范围查询 支持直接在密文上进行范围查询、排序
典型算法 FF1、FF3、VAES3 Boldyreva OPE、CLWW、mOPE
应用场景 信用卡、身份证、手机号脱敏 数据库加密、范围检索、排序索引

嗯,这里要注意:保序加密因为泄露了大小顺序,信息量比保形加密多,所以理论上安全强度会打折扣。你如果既要求格式不变又要求顺序保持,那就得用复合方案——比如先保形再保序,或者反过来。但这样会导致复杂度飙升。

2.4 应用场景与选型建议

  • 纯保形需求:你只需要格式不变,不需要做任何大小比较。比如脱敏后的数据用于展示、打印、接口对接。用FF1或FF3。
  • 纯保序需求:你需要在加密数据上做范围查询、B+树索引、排序聚合。用Boldyreva OPE或者更先进的mOPE(可调节的保序加密)。
  • 二者都不能满足的情况:如果你既需要格式不变又需要顺序查询……我个人建议重新考虑设计。很多时候可以把格式和顺序拆开处理:一个字段存保形加密的结果用于展示,另一个字段存保序加密的结果用于查询,两列分开维护。

我从项目里学到的经验

我习惯在选型前先画一个决策树:问自己三个问题——1)下游系统对格式有没有硬依赖?2)查询语句里是否需要BETWEEN、ORDER BY或MIN/MAX?3)能否接受密文长度变化?然后对着上表对号入座,基本不会选错。

保形加密 vs 保序加密 核心流程对比 原始明文 (格式固定) 保形加密 (FF1/FF3) 密文 (格式与明文相同) 原始明文 (数值有序) 保序加密 (Boldyreva OPE) 密文 (保持大小顺序) 左支:格式不变,顺序打乱;右支:顺序保留,格式无限制 选型时优先问自己:到底要保“形”还是保“序”?