常见令牌化技术:从随机到可逆

说到令牌化,其实就三大流派。我这些年做项目,三种都碰过,各有各的坑。今天我把它们捋清楚。

随机令牌生成

这是最直白的方式。说白了,就是给原始数据随机分配一个占位符。

  • 生成方式:用安全随机数生成器(CSPRNG)产生固定长度的字节串,然后做 Base64 或 HEX 编码。
  • 映射关系:令牌和原始值之间没有数学联系,全靠一张映射表。
  • 典型场景:支付卡号(PAN)替换,PCI DSS 合规。
我的经验:我在一个电商项目中用过随机令牌。当时觉得简单,后来发现查表性能是瓶颈。千万级记录,每次令牌化都要查一次数据库,延迟一下子就上去了。
// 伪代码:生成随机令牌
function generateToken(length) {
    const bytes = crypto.randomBytes(length);
    return bytes.toString('hex');
}
随机令牌优缺点对比
优点缺点
安全性高,无法逆向需要维护大映射表
实现简单表膨胀后性能急剧下降
无固定输出长度限制数据丢失后无法恢复

哈希令牌

用哈希函数对明文做单向处理,输出固定长度的摘要。

  • 常见算法:SHA-256、SHA-3。搭配盐值(salt)防止彩虹表攻击。
  • 为什么还需要加盐?因为纯哈希相同输入永远相同,容易被遍历。
  • 注意:哈希是不可逆的。你没法从令牌反算出原文。
避坑指南:我曾经见过一个客户,直接拿 MD5 做令牌化,而且不带盐。三个月后黑客凭彩虹表把整张用户表反推出来了……嗯,从那以后我再也不敢用弱哈希做令牌化。
// 加盐哈希令牌示例
const salt = crypto.randomBytes(16).toString('hex');
const hash = crypto.createHash('sha256')
    .update(data + salt)
    .digest('hex');

哈希令牌的好处是不需要维护映射表。但坏处也明显:

  • 如果原始数据有规律(比如身份证号前6位是地区码),哈希结果依然有碰撞风险。
  • 令牌长度固定(比如256位),有些旧系统存不下。
适用场景:数据只需要做关联查询,不需要还原原文。比如日志脱敏、用户ID匿名化。

可逆令牌(基于FPE)

这才是今天的主角。FPE——格式保留加密,能让你加密后的数据保持原始格式。

  • 核心思路:用对称加密算法(如AES),配合FF1/FF3等模式,在保持数据格式的前提下完成加密。
  • 效果:明文"123456789"加密后依然是9位数字,比如"847391265"。
  • 为什么需要它?很多遗留系统对数据格式有硬性要求。比如信用卡号必须是16位数字,邮编只能是5位数字。普通加密改用Base64就全乱了。

我在一个银行项目中,需要把客户的社保号(SSN)做令牌化。SSN的格式是9位数字,划成3-2-4的段。如果用随机令牌,后端对接的系统会直接报错,因为它校验位不对。后来我上了FPE,加密后依然是9位数字,校验位也自己重新计算,系统完全无感。

// 使用FF1模式加密示例(Python-like)
from ff1 import FF1
cipher = FF1(key, radix=10)   # 数字域,radix=10
plaintext = "123456789"
ciphertext = cipher.encrypt("", plaintext)  # 输出"847391265"
特性随机令牌哈希令牌FPE令牌
可逆性需查表否是(有密钥)
格式保留否否是
性能依赖数据库快(本地计算)快(本地计算)
安全性极高高(加盐)高(基于AES)
典型场景支付令牌日志脱敏遗留系统集成的令牌化
什么时候该选FPE?你想想看,如果下游系统对数据格式有强校验(比如正则表达式、校验位、长度限制),那FPE就是唯一解。
三种令牌化技术对比 随机令牌生成 查表映射 格式不保留 哈希令牌 单向函数 无需存储 FPE令牌 加密+格式保留 可逆向解密 如何选型? 需要可逆 + 格式保留 → FPE 只需要单向匿名化 → 哈希(加盐) 不关心格式、有映射表 → 随机令牌 注意:随机令牌的表会随数据量线性膨胀,FPE无此问题 哈希令牌无法还原,丢失密钥等于永久丢失
重要提醒:FPE虽然方便,但它不是万能药。加密后的数据依然在同一个值域内,如果你对数据做频率分析,依然可能泄露信息。比如某地区邮政编码只有几个,加密后如果只保留5位,攻击者可以通过频次推断。这种情况下,我建议你结合随机噪声或动态盐值来补强。

三种技术,没有的优劣。我自己的习惯是:

  • 对接外部系统且要求格式不变 → 优先FPE
  • 内部数据只做聚合分析 → 哈希令牌(加盐)
  • 支付数据合规或需要细粒度控制 → 随机令牌

嗯,就这样。别以为令牌化很简单,选错了方案,后面改起来真要命。