编码、加密与令牌化

这张图想表达:Encoding(编码)解决“表示/传输/兼容”,Encryption(加密)解决“保密”,Tokenization(令牌化)解决“把敏感数据替换成无敏感意义的占位符,并把映射关系集中管控”。下面按图逐块拆开讲,并顺便指出图里一个常见“误导点”。


1) Encoding(编码)——“换个写法”,不是“上锁”

图中上半部分:plain text → algorithm →(图里写 cipher text)→ decoding → plain text

本质:把数据从一种表示转换成另一种表示,方便存储/传输/解析/跨系统。

关键点

不以保密为目标:通常不需要密钥,别人知道规则就能还原。

可逆:encode/decode 成对出现(只要规则一致)。

输出不是“密文”:图里把编码结果画成“cipher text + 锁”,容易让人误以为编码=加密;正确理解是:编码结果只是另一种表示

典型用例(图右侧)

ASCII / UTF-8:字符到字节的编码。

Base64:把二进制变成可打印字符,便于放进 JSON/URL/邮件;Base64 绝不是加密

Protocol Buffers(Protobuf):结构化数据的二进制序列化格式(更紧凑、跨语言)。


2) Encryption(加密)——“上锁”,需要密钥,目标是保密(以及完整性)

图中中间部分:plain text → algorithm + key → cipher text;cipher text → algorithm + key → plain text

本质:在攻击者可见数据的情况下,也尽量让其无法读懂内容

关键点

必须有密钥:没有密钥就不能还原(理想情况下)。

两大类

对称加密:同一把密钥加/解(AES-GCM、ChaCha20-Poly1305),速度快,适合大数据。

非对称加密:公钥加密、私钥解密;或用于签名(RSA/ECDSA/Ed25519)。现实系统里常用于“协商对称密钥/身份认证”,而不是直接加密大文件。

别只谈“保密”:工程上更常用 AEAD(如 AES-GCM),同时保证机密性 + 完整性(防篡改)

典型用例(图右侧)

HTTPS/TLS:传输加密 + 身份认证(证书)+ 完整性。

Email encryption:如 S/MIME、PGP。

Blockchain wallet:私钥保护/签名(钱包更核心是“签名证明所有权”,不只是加密)。


3) Tokenization(令牌化)——“替换”,让业务系统不再持有敏感明文

图中下半部分:PAN(卡号)→ 请求 token → TSP/Token Vault → 返回 token;需要时 lookup token → 得到 PAN

本质:用一个无敏感含义的 token替代敏感数据(如 PAN 卡号、身份证号)。真正的敏感值放在Token Vault(令牌库/保险库)里集中保管。

关键点

token 本身不等于密文:它通常不包含可解出的原文信息(很多实现是随机值或受控格式)。

可逆方式是“查表/解令牌”:通过 Token Service(TSP 或自建)进行 detokenize/lookup,而不是“拿密钥解密”。

安全边界在 Vault:Vault 的权限、审计、隔离、HSM/密钥、网络分区,比 token 字符串本身更重要。

合规价值:让大多数系统只处理 token,从而缩小 PCI DSS 等合规范围(注意:是否“降范围”取决于架构和审计口径,但这是 tokenization 的核心动机之一)。

典型用例(图右侧)

信用卡令牌化(PAN→token):电商/支付场景常见(Visa/Mastercard 的网络令牌化、或支付机构自建)。

PCI DSS:减少存储/处理真实 PAN 的系统数量。

Financial Data Sharing:给合作方/内部系统发 token,而不是发真实敏感字段。


4) 三者怎么选?一张“工程决策表”

维度 编码 Encoding 加密 Encryption 令牌化 Tokenization
目的 兼容/表示/传输/序列化 保密(+完整性) 替换敏感数据、降低暴露面/合规范围
是否需要密钥 通常不需要 必须需要(或证书体系) 通常不靠“解密”,而靠“Vault/服务权限”
是否可逆 可逆(decode) 可逆(decrypt,需密钥) 可逆(detokenize,需访问 Vault/服务)
攻击者拿到结果 轻松还原 理论上很难还原 token 本身没意义,但若 Vault 被攻破则风险大
常见例子 UTF-8、Base64、Protobuf、JSON TLS、AES-GCM、PGP PAN token、SSN token、内部 ID token

5) 常见误区(这张图最容易引发的)

把编码当加密:Base64、Hex、URL 编码都不是保密措施。

把“token”当“密文”:tokenization 更像“受控映射 + 权限隔离”,不是纯密码学变换。

以为加密就能大幅降低合规范围:很多合规里“你还在存真实敏感数据(即便加密)= 仍在范围内”,而 tokenization 才是“让业务系统根本不碰敏感原文”的思路。

漏掉哈希(Hashing):密码存储通常用哈希(带盐、慢哈希如 bcrypt/Argon2),它既不是编码也不是可逆加密/令牌化。

我用一个常见的“Delphi 后端 + PostgreSQL + Redis + 对外 REST API”的业务栈,把 编码 / 加密 / 令牌化分别放到哪些位置、怎么组合、踩坑点一次讲透(偏工程实践)。


1) 一张“从入口到落库”的放置地图(该用谁就用谁)

A. API 层(HTTP/REST)

传输层:用加密(TLS/HTTPS)

目的:防窃听、防篡改、服务器身份认证(证书)。

结论:只要走公网,就默认 HTTPS;内部服务也最好 mTLS 或至少 TLS。

报文格式:用编码/序列化(JSON / Protobuf)

JSON/UTF-8:可读、通用

Protobuf:更省带宽、更快、强 schema

不要把 Base64 当安全

Base64 只用于“让二进制能塞进文本协议”,例如上传图片、签名字段。

B. 应用层(业务逻辑/日志/缓存)

日志:尽量只记录 token 或脱敏后的片段

例如卡号只留
**** **** **** 1234
,或只留 token。

这是最常见的数据泄露入口之一(比数据库还常见)。

缓存/消息队列:优先放 token,不放敏感原文

Redis、MQ、任务队列都属于“扩散面”,敏感数据一放进去就很难彻底清理与审计。

C. 数据库层(持久化)

这里按数据类型分三类最清晰:

密码(Password)→ 用哈希(不是编码/加密/令牌化)

存:
Argon2id/bcrypt + salt
(不可逆)

验证:重算哈希比对

绝对不要:Base64、AES 直接加密密码、MD5/SHA1 直哈希

需要“可读明文”的敏感字段(例如地址、身份证、私密备注)→ 用加密

典型:应用层字段加密(Field-level encryption),落库存密文

推荐:AEAD(AES-GCM / ChaCha20-Poly1305),一条记录一个随机 nonce/IV

索引/查询:会变麻烦(见第 4 节“查询难题”)

高敏感且频繁流转的数据(例如 PAN 卡号)→ 用令牌化

库里只存 token(以及少量元数据:last4、brand、exp_month)

真正 PAN 在 Token Vault/支付机构/PCI 隔离区

业务系统处理“支付”只用 token 调支付网关


2) 三种“经典组合方案”(你选其一就很稳)

方案 1:大多数普通业务系统(无支付卡号自存)

HTTPS(加密传输)

DB:密码哈希;其余敏感字段用加密(可选)

日志/缓存:脱敏

优点:实现成本低

缺点:一旦业务要存 PAN,会立即进入高压合规/隔离

方案 2:有支付,但 不碰 PAN(推荐)

支付:走 PSP(Stripe/Adyen 等)或网络令牌(Visa/Mastercard token)

你系统里:只存 payment_token + last4

优点:合规压力最小;数据面最干净

缺点:依赖外部 token 服务

方案 3:你必须存极敏感数据(被迫 PCI/金融内控)

建 Token Vault(独立服务+独立库+最小人员权限+强审计)

业务库只存 token

Vault 内部的敏感原文也可以再加密(双保险)

优点:爆炸半径可控

缺点:工程、运维、审计成本高


3) “令牌化”在系统里到底怎么落地(按你图里的 TSP/Vault)

令牌化服务(Token Service)通常提供:


Tokenize(plaintext) -> token


Detokenize(token) -> plaintext
(权限极严)


GetMetadata(token) -> last4/类型/有效期
(权限可更宽)

强烈建议:业务系统默认只有“metadata 权限”,没有 detokenize 权限。
真正需要明文的场景(比如与银行侧清算)放到隔离域里跑。

Vault 的关键不是“表结构”,而是:

网络隔离(只允许少数服务访问)

强鉴权(mTLS + service identity + RBAC)

审计(谁在何时 detokenize 了什么)

HSM/密钥托管(如果 Vault 内还有加密)


4) 字段加密最难的点:怎么查询/排序/去重?(避坑指南)

你一旦把
email/phone/idno
加密存库,会遇到:

无法 where = ?(因为密文每次都不同:随机 IV/nonce)

无法做 LIKE 模糊查询

无法索引排序/范围查询

常见工程解法(按安全性从强到弱):

分层:明文不落库 + token 化(最推荐)

“加密字段 + 额外存一个哈希索引列”(常用折中)


email_ciphertext
存 AES-GCM 密文


email_hash

HMAC-SHA256(normalized_email, server_secret)

查询用
email_hash = HMAC(...)
命中后再解密校验

注意:不要用普通 SHA256(email) 这种容易被字典/撞库推断

确定性加密(Deterministic Encryption)(不太推荐)

好处:可等值查询/索引

坏处:相同明文→相同密文,泄露统计特征,风险更高


5) Delphi 落地要点(不写长代码也能把思路讲清)

加密库选择

Windows 上别自己“拼 AES + padding + MAC”,优先用成熟实现:

OpenSSL(你本来就很熟悉生态)

或 Windows CNG/BCrypt(系统自带,维护成本低)

AEAD 模式必备字段


ciphertext


nonce/iv


tag
(如果库把 tag 单独给你)


aad
(可选,用来绑定记录上下文,如 user_id、version,防剪切粘贴攻击)

密钥管理

密钥不要写死在 exe;至少环境变量/配置中心/密钥文件权限隔离

轮换:加密数据要带
key_id
/
version
,便于逐步重加密


6) 一句话总结(你做架构决策时的“口诀”)

Encoding:为了“能传、能存、能互通”

Encryption:为了“别人拿到也看不懂(还难改)”

Tokenization:为了“业务系统压根就别碰敏感原文,把风险关进 Vault”

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
一池锦鲤伴风华的头像 - 鹿快
评论 抢沙发

请登录后发表评论

    暂无评论内容