第1章 密码学基础回顾:对称加密、非对称加密与哈希函数
说实话,很多人一上来就学可搜索加密,结果发现缺了密码学底子,看公式跟看天书一样。我当年也是这么踩坑的——啃了半个月,最后发现自己连 AES 和 RSA 的区别都说不清楚。那这节课,我们就从最核心的三个工具讲起:对称加密、非对称加密、哈希函数。你搞懂了它们,后面盲索引、可搜索加密的方案才能真正落地。
1.1 对称加密:AES 是怎么工作的?
对称加密,说白了就是一把钥匙开一把锁。加密和解密用的是同一个密钥。你想想看,这个场景就像你用同一把钥匙锁门、开门。方便是方便,但钥匙怎么安全地交给对方?这就是密钥分发的问题。
AES(Advanced Encryption Standard)是目前最主流的对称加密算法。它支持 128、192、256 位密钥,咱们工程里最常见的是 AES-256。
原理简述
- 分组加密:把明文分成 128 位(16 字节)一组,逐组处理。
- 轮运算:AES-128 做 10 轮,AES-192 做 12 轮,AES-256 做 14 轮。每轮包括字节代换、行移位、列混合、轮密钥加。
- 初始化向量(IV):为了抵抗模式攻击,一般用 CBC、CTR、GCM 等模式。IV 每次随机生成,不需要保密。
个人经验:我在做数据库加密时,一开始就用了 AES-ECB 模式。结果发现相同明文块会加密成相同密文,等于没隐藏数据模式。后来赶紧换成 AES-GCM——既保密又带认证,防篡改。别踩这个坑。
| 特性 | AES-256 |
|---|---|
| 密钥长度 | 256 位 |
| 安全级别 | 极高(量子计算除外) |
| 典型应用 | 文件加密、HTTPS 会话、数据库字段加密 |
| 性能 | 硬件加速后非常快(Intel AES-NI) |
实际项目中,我建议你优先选择 AEAD 模式(如 AES-GCM、ChaCha20-Poly1305)。它同时保证机密性和完整性,一步到位。
1.2 非对称加密:RSA 与 ECC
非对称加密就解决了一个核心问题:如何安全地分发密钥?它用一对密钥——公钥公开,私钥自己保管。别人用你的公钥加密,只你能用私钥解密。你也可以用自己的私钥签名,别人用公钥验签。
RSA:经典但笨重
RSA 基于大整数因数分解难题。1024 位已经被认为不安全,现在至少 2048 位,推荐 4096 位。但位数一大,速度就慢,尤其私钥操作。
- 加密:
c = m^e mod n,公钥 (e,n) - 解密:
m = c^d mod n,私钥 d - 签名:私钥签名,公钥验签
我曾经在一个老旧系统上用过 RSA-2048 做密钥交换,每次握手要花几十毫秒,用户都抱怨。后来换成 ECDH 就好多了。
ECC:更小、更快、更安全
ECC(椭圆曲线密码)基于椭圆曲线离散对数难题。256 位的 ECC 安全性与 3072 位 RSA 相当,但密钥小、速度快。常见曲线有 secp256k1(比特币用)、P-256(NIST 标准)、Curve25519(现代应用推荐)。
| 特性 | RSA-2048 | ECC P-256 |
|---|---|---|
| 密钥长度 | 2048 位 | 256 位 |
| 签名速度(私钥) | 慢 | 快 |
| 安全等级 | 112 位 | 128 位 |
| 典型应用 | 旧系统、证书 | 现代 TLS、区块链 |
注意:ECC 不能像 RSA 那样直接“加密”任意长度的数据。它一般用来做密钥协商(ECDH)或数字签名(ECDSA)。真正的数据加密还是交给对称加密。
1.3 哈希函数:SHA-256 到底在算什么?
哈希函数不是加密,它没有密钥。它的作用是把任意长度的输入变成固定长度的“指纹”。SHA-256 输出 256 位(32 字节)。
- 单向性:从哈希值反推原文不可行。
- 抗碰撞:找到两个不同输入具有相同哈希值基本不可能。
- 雪崩效应:输入改一个 bit,输出一半 bit 都变。
我举个实际场景:你下载一个 10GB 的 Linux 镜像,怎么确认没被篡改?官网给一个 SHA-256 校验值,你在本地算一遍,如果一致就放心。这就是哈希的完整性校验。
在密码学协议里,哈希还经常用来做消息认证码(HMAC)、密钥派生(HKDF)、数字签名中的摘要。可搜索加密里,哈希常被用来构造“盲索引”——给关键字加盐然后哈希,隐藏关键字本身的模式。
避坑指南:我曾经在项目中直接用SHA256(password)做密码存储,结果被安全审计骂惨了。哈希函数太快,容易被暴力破解。正确做法是加慢哈希(如 bcrypt、Argon2)或迭代多次(PBKDF2)。SHA-256 本身不适合密码存储。
1.4 三者的协作关系
实际工程里很少只用一种。一个典型的加密通信过程是这样的:
- 双方用非对称加密(如 ECDH)协商出一个临时对称密钥。
- 用对称加密(如 AES-GCM)加密实际数据。
- 用哈希函数(如 SHA-256)生成消息摘要,配合对称密钥做认证。
- 可选地用数字签名(如 ECDSA)保证消息来源不可抵赖。
你看,每个工具各司其职。我自己在做可搜索加密的时候,也是先搭好这个底层工具箱,再往上构造盲索引和陷门。
1.5 回到可搜索加密的视角
搞懂了这三样东西,你再看可搜索加密就清晰多了:
- 对称加密用来加密文档本身。
- 哈希函数把关键字“盲化”成索引标签,这样服务器看不懂关键字但能匹配。
- 非对称加密有时用来做代理重加密或密钥分发。
很多初学者会问我:为什么不能直接用 AES 加密关键字然后搜索?嗯,这里要注意——AES 密文是随机分布的,服务器无法在不解密的情况下判断“密文 A”和“密文 B”是不是同一个关键字。所以我们需要盲索引这种特殊结构,而盲索引的核心就是哈希加盐。
我个人习惯是:先把这三个基础算法的标准库接口背下来(比如 Python 的 cryptography 或 Go 的 crypto/aes),然后动手写一个小工具:用 AES-256-GCM 加密一个文件,用 RSA-2048 签名一份消息,用 SHA-256 校验文件完整性。边写边理解它们的 IO 和性能特点。
# 示例:AES-256-GCM 加密(Python)
from cryptography.fernet import Fernet
key = Fernet.generate_key() # 32 字节
cipher = Fernet(key)
= cipher.encrypt(b"Hello, world!")
print()
# 解密
original = cipher.decrypt()
print(original.decode())