第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-2048ECC 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 三者的协作关系

实际工程里很少只用一种。一个典型的加密通信过程是这样的:

  1. 双方用非对称加密(如 ECDH)协商出一个临时对称密钥。
  2. 用对称加密(如 AES-GCM)加密实际数据。
  3. 用哈希函数(如 SHA-256)生成消息摘要,配合对称密钥做认证。
  4. 可选地用数字签名(如 ECDSA)保证消息来源不可抵赖。

你看,每个工具各司其职。我自己在做可搜索加密的时候,也是先搭好这个底层工具箱,再往上构造盲索引和陷门。

密码学基础三大核心工具 密码学基础三大核心工具 对称加密(AES) 非对称加密(RSA/ECC) 哈希函数(SHA-256) 联合应用:加密通信、数字签名、密钥协商 分组加密 · 密钥128/192/256位 公钥私钥 · 密钥交换/签名 单向 · 抗碰撞 · 固定输出 典型应用场景 文件加密 HTTPS/TLS 数字签名 可搜索加密 三者各司其职,共同构成可搜索加密的底层密码学基石

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())