加密基础回顾:对称加密、非对称加密、哈希函数
在做密文查询之前,我得先跟你把加密基本功捋一遍。你想想看,密码学就像一把锁——你连锁的种类都不知道,怎么谈得上"在锁上做查询"?
我刚开始接触密文查询那会儿,以为只要会把数据加密存起来就行。后来踩了不少坑,才意识到:选错加密算法,查询性能可能差几百倍。这一章我们就聚焦三类核心加密工具:对称加密、非对称加密和哈希函数,以及它们各自在密文查询里的"用武之地"。
对称加密:快,但密钥管理是硬伤
对称加密,说白了就是加密和解密用同一把钥匙。好比你家大门,一把钥匙既能锁也能开。典型算法有 AES、SM4、ChaCha20。
我在项目中用过 AES-256-GCM 做全字段加密。速度确实快,在普通服务器上每秒能处理几百 MB 的数据。但问题也跟着来——
来看一个 AES-CBC 加解密的示例(Python + PyCryptodome):
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import os
key = os.urandom(32) # 256-bit key
iv = os.urandom(16) # 随机IV,每次不同
def encrypt(plaintext):
cipher = AES.new(key, AES.MODE_CBC, iv)
ct = cipher.encrypt(pad(plaintext.encode(), 16))
return iv + ct # 把IV拼在密文前面
def decrypt(ciphertext):
iv = ciphertext[:16]
ct = ciphertext[16:]
cipher = AES.new(key, AES.MODE_CBC, iv)
return unpad(cipher.decrypt(ct), 16).decode()
你看,如果每次 IV 都不同,encrypt("alice") 每次返回的密文都不一样。直接 WHERE ciphertext = ? 肯定查不到。但如果放弃随机 IV,用固定 IV 做确定性加密,又会引入一定的安全性风险。这是个经典权衡。
| 特性 | 概率性加密(随机 IV) | 确定性加密(固定 IV) |
|---|---|---|
| 安全性 | 高(相同明文 → 不同密文) | 中(模式可被分析) |
| 直接等值查询 | 不支持 | 支持 |
| 典型场景 | 数据存储 | 密文索引/查询 |
非对称加密:安全分发,但慢得让人心疼
非对称加密有两把钥匙——公钥加密,私钥解密。RSA 和 ECC 是主力。你想想看,这在密文查询里怎么用?
我习惯把非对称加密当作"密钥交换的桥梁",而不是直接加密大量数据。原因很简单:RSA-2048 加密 256 字节就要花几毫秒,而 AES 加密同样数据只要几微秒,差了两到三个数量级。
但在某些密文查询方案中(比如非对称可搜索加密),公钥加密正好派上用场:
核心痛点总结:
- 加密/解密速度比对称加密慢 100-1000 倍
- 密文膨胀严重(RSA-2048 加密 256 字节 → 输出 256 字节,但实际有效载荷只有 32 字节左右)
- 抗量子攻击能力弱(Shor 算法基本可以瓦解 RSA/ECC)
哈希函数:单向的指纹机
哈希函数把任意长度的数据映射成固定长度的摘要。SHA-256、SHA-3、SM3 都是常客。它有三个关键特性:不可逆、抗碰撞、雪崩效应(输入改一位,输出面目全非)。
在密文查询里,哈希函数最常见的作用就是构建关键字索引。举个例子:
import hashlib
keyword = "username:alice"
# 直接用哈希——不安全,因为字典攻击
h = hashlib.sha256(keyword.encode()).hexdigest()
# 加盐哈希——我推荐这种做法
salt = os.urandom(16)
h_salted = hashlib.pbkdf2_hmac('sha256', keyword.encode(), salt, 100000)
你想想看,如果直接用 SHA256("alice") 做密文索引,坏人直接穷举常见用户名,很快就能把数据库里的密文和明文对应起来。所以我在项目里只要涉及到哈希索引,一定会加盐或者做哈希拉伸(比如 PBKDF2、bcrypt)。
三者如何协同——一张关系图
光讲概念容易晕。我把这三个工具在密文查询里的职责梳理成下面这张图:
实战中的选型建议
说了这么多,你可能会问:我的密文查询系统到底该用哪个?
我一般这样判断:
- 如果只需要等值查询,优先考虑确定性对称加密 + 加盐哈希索引。性能和安全性都说得过去。
- 如果需要范围查询或模糊匹配,对称加密基本帮不上忙,得靠保序加密或可搜索加密的变体(那又是后面的章节了)。
- 如果需要多用户写入,非对称加密的陷门机制更合适——每个用户用自己的私钥生成查询令牌,服务端不需要知道明文。
嗯,加密基础就聊到这儿。你先把这几种工具的差异吃透,后面章节里我们会一步步把它们搭成真正的密文查询系统。